home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 25 / AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso / Updates / HD-Installer / jst_dev / docs / engonly / jotdstartup.doc < prev    next >
Text File  |  2000-04-12  |  86KB  |  3,005 lines

  1. TABLE OF CONTENTS
  2.  
  3. JOTDStartup/JOTD HD Startup code autodocs
  4. JOTDStartup/Memory setup
  5. JOTDStartup/Calling the user code
  6. JOTDStartup/Useful macros
  7. JOTDStartup/STORE_REGS-RESTORE_REGS
  8. JOTDStartup/Console output
  9. JOTDStartup/PatchMacros
  10. JOTDStartup/CallMacros
  11. JOTDStartup/Compelling Macros
  12. JOTDStartup/MiscMacros
  13. JOTDStartup/Relocatable Memory operations
  14. JOTDStartup/Registers: CAUTION!
  15. JOTDStartup/JoypadState()
  16. JOTDStartup/GetUserData()
  17. JOTDStartup/GetUserFlags()
  18. JOTDStartup/SetLocalVarZone()
  19. JOTDStartup/SetFilesPath()
  20. JOTDStartup/UseHarryOSEmu()
  21. JOTDStartup/DisableChipmemGap()
  22. JOTDStartup/ReadUserDir()
  23. JOTDStartup/SaveOSData()
  24. JOTDStartup/Reboot()
  25. JOTDStartup/AllocExtMem(), Alloc24BitMem()
  26. JOTDStartup/OpenFakeExec()
  27. JOTDStartup/FreezeAll()
  28. JOTDStartup/LoadDisks()
  29. JOTDStartup/LoadDisksIndex()
  30. JOTDStartup/LoadDiskFromName()
  31. JOTDStartup/LoadSmallFiles()
  32. JOTDStartup/LoadFiles()
  33. JOTDStartup/GetFileLength()
  34. JOTDStartup/TestFile()
  35. JOTDStartup/TestFileAbs()
  36. JOTDStartup/LoadRNCFile()
  37. JOTDStartup/TransfRoutines()
  38. JOTDStartup/BlockFastMem()
  39. JOTDStartup/Degrade()
  40. JOTDStartup/Enhance()
  41. JOTDStartup/DegradeGfx()
  42. JOTDStartup/DegradeCpu()
  43. JOTDStartup/Display()
  44. JOTDStartup/CloseAllQuiet()
  45. JOTDStartup/CloseAll()
  46. JOTDStartup/FlushCachesSys()
  47. JOTDStartup/GetMemFlag()
  48. JOTDStartup/TestxMbChip()
  49. JOTDStartup/CheckAGA()
  50. JOTDStartup/GetSR()
  51. JOTDStartup/GetAttnFlags()
  52. JOTDStartup/WriteFileHD()
  53. JOTDStartup/WriteUserFileHD()
  54. JOTDStartup/ReadUserFileHD()
  55. JOTDStartup/ReadFile()
  56. JOTDStartup/ReadFilePart()
  57. JOTDStartup/ReadFilePartHD()
  58. JOTDStartup/ReadFileHD()
  59. JOTDStartup/DeleteFileHD()
  60. JOTDStartup/DeleteUserFileHD()
  61. JOTDStartup/InGameOSCall()
  62. JOTDStartup/PatchExceptions()
  63. JOTDStartup/FlushCachesHard()
  64. JOTDStartup/GoECS()
  65. JOTDStartup/ResetDisplay()
  66. JOTDStartup/ResetSprites()
  67. JOTDStartup/KickVerTest()
  68. JOTDStartup/Kick37Test()
  69. JOTDStartup/InitTrackDisk()
  70. JOTDStartup/TrackLoad
  71. JOTDStartup/SetTDUnit()
  72. JOTDStartup/ReadFileFast()
  73. JOTDStartup/ReadRobSectors()
  74. JOTDStartup/ReadDiskPart()
  75. JOTDStartup/StrcpyAsm()
  76. JOTDStartup/StrcmpAsm()
  77. JOTDStartup/StrlenAsm()
  78. JOTDStartup/ToUpperAsm()
  79. JOTDStartup/HexReplaceLong()
  80. JOTDStartup/HexReplaceWord()
  81. JOTDStartup/SetFakeFunction()
  82. JOTDStartup/CRC16()
  83. JOTDStartup/HexToString()
  84. JOTDStartup/Save & Restore hardware registers
  85. JOTDStartup/RNCLength()
  86. JOTDStartup/RNCDecrunch()
  87. JOTDStartup/RNCDecrunchEncrypted()
  88. JOTDStartup/ATNDecrunch()
  89. JOTDStartup/PPDecrunch()
  90. JOTDStartup/FungusDecrunch()
  91. JOTDStartup/BlackScreen()
  92. JOTDStartup/EnterDebugger()
  93. JOTDStartup/SetTraceVector()
  94. JOTDStartup/WaitMouse()
  95. JOTDStartup/WaitMouseInterrupt()
  96. JOTDStartup/InGameExit()
  97. JOTDStartup/IsRegistered()
  98. JOTDStartup/SetExitRoutine()
  99. JOTDStartup/InGameIconify()
  100. JOTDStartup/PatchMoveCList_Abs()
  101. JOTDStartup/PatchMoveCList_Ind()
  102. JOTDStartup/PatchMoveCList_Idx()
  103. JOTDStartup/PatchMoveBlit_Idx()
  104. JOTDStartup/StoreCopperPointer()
  105. JOTDStartup/TellCopperPointer()
  106. JOTDStartup/BeamDelay()
  107. JOTDStartup/WaitBlit()
  108. JOTDStartup/SetQuitKey()
  109. JOTDStartup/SetIconifyKey()
  110. JOTDStartup/LogPatch()
  111. JOTDStartup/InitLogPatch()
  112. JOTDStartup/The printlog tool
  113. JOTDStartup/JOTD HD Startup code autodocs
  114.  
  115.  
  116. ***************************************************************************
  117.  
  118.                         JOTD Startup V3.2b
  119.             © Copyright 1995-99 Jean-François Fabre/Ralf Huvendiek
  120.  
  121. ***************************************************************************
  122.  
  123.  
  124.          Memory setup           
  125.          Starting your code     
  126.          Why decrunch routines ?
  127.  
  128.          Macros                 
  129.          Library Functions      
  130.  
  131.          The printlog tool      
  132.  
  133.          Contact us             
  134.  
  135.  
  136. -----------------------------------------------------------------------------
  137. Converted using GuideML V1.6, a converter written by Richard Körber
  138. <shred@chessy.aworld.de>
  139.  
  140.  
  141. JOTDStartup/Memory setup
  142.  
  143.  
  144. To understand some choices and notions, you have to know how the memory
  145. is organized by my loading routines:
  146.  
  147. On a fastmem amiga:
  148.  
  149. V39:
  150.  
  151. High Fast: User object, General reloc routines, disks images or RAM files,
  152.            OS chip mirror, extension mem (for the 1MB games) (if any)
  153. Fast: The JOTDStartup program routines not relocated.
  154. Low Chip: The game (can take 512K, 1024K or 2048K)
  155.  
  156. Older than V39:
  157.  
  158. Fast: User object, General reloc routines, disks images or RAM files,
  159.            OS chip mirror, extension mem (for the 1MB games) (if any),
  160.            the HD load program
  161. Low Chip: The game (can take 512K, 1024K or 2048K)
  162.  
  163.  
  164. On a chip only amiga (V39):
  165.  
  166. High Chip: User object, General reloc routines, disks images or RAM files,
  167.            OS chip mirror, extension mem (for the 1MB games) (if any)
  168. Chip: The game, The JOTDStartup program routines not relocated.
  169.  
  170. Obviously, while the game is running, you cannot call non-relocated routines
  171. (the ones callable with JSRABS), or else it will crash. You won't need
  172. those routines anyway during the game (you can use JSRABS routines in
  173. a code called using InGameOSCall)
  174.  
  175. If the game needs more than 512K to run, you'll have to find where the expansion
  176. memory detection is done to replace it by a pointer on the extension mem you allocated
  177. with AllocExtMem(), else the game can crash (older than V39)
  178.  
  179. The NOFAST tooltype will try to allocate chipmem for AllocExtMem unless you've got
  180. no chipmem above $80000 (the assumed chip size before you make a SaveOSData())
  181. In this case it will return 0 (it's useless to allocate mem that will be overwritten by
  182. the game)
  183.  
  184. Note: If you succeed in tracking the game memory 'allocation', you don't need relocatable
  185. routines, and nothing will overwrite your code,
  186. but it depends on which level of quality you want when you program your installers...
  187. And this is also compulsory if you want to install a clean quit option!
  188.  
  189. In the case you would like to leave some OS code done by the game, JST supports ExecBase
  190. emulation since V0.7. Some calls are supported, others are redefinable by the user,
  191. (see OpenFakeExec() function)
  192.  
  193.  
  194.  
  195.  
  196. JOTDStartup/Calling the user code
  197.  
  198.  
  199. Your relocatable object file will be loaded by JST and it will be checked
  200. against relocatable symbols. For instance, you cannot do things like:
  201.  
  202.     move.l    #20,var
  203.     
  204. because this instruction needs relocation, and we can't afford it since
  205. JST is not yet able to do this. Instead you can use one of the reloc macros.
  206. This instruction will become:
  207.  
  208.     RELOC_MOVEL    #20,var
  209.     
  210. JST passes some arguments in registers:
  211.  
  212. D0.L: 0 if no trainer detected via tooltypes/args, -1 if trainer requested
  213. D1.L: 0 if OS swap is allowed, -1 if not (see InGameOsCall())
  214. D2.L: -1 if JOYPAD is set in the tooltypes, 0 else 
  215. D3.L: -1 if HDLOAD is set in the tooltypes, 0 else 
  216. D4.L: -1 if BUTTONWAIT is set in the tooltypes, 0 else 
  217. D5.L: -1 if LOWMEM is set in the tooltypes, 0 else 
  218.  
  219. The others (function tables) are passed in the HD_PARAMS structure.
  220. Use the macros, and don't fool with the variables in HD_PARAMS.
  221.  
  222.  
  223.  
  224.  
  225. JOTDStartup/Useful macros
  226.  
  227.  
  228. Some of these macros are compulsory for a good compilation and linking
  229. of the user program. They are compatible with phxass and should cause no
  230. problem with other assemblers.
  231.  
  232.  
  233.          STORE_REGS          
  234.          RESTORE_REGS        
  235.  
  236.          Mac_printf          
  237.          PUTS                
  238.          NEWLINE             
  239.  
  240.          GETUSRADDR          
  241.          GETGENADDR          
  242.          PATCHUSRJMP         
  243.          PATCHUSRJSR         
  244.          PATCHABSJMP         
  245.          PATCHABSJSR         
  246.          PATCHGENJMP         
  247.          PATCHGENJSR         
  248.  
  249.          JSRGEN              
  250.          JSRGEN_FREEZE       
  251.          JMPGEN              
  252.          JSRABS              
  253.          JMPABS              
  254.  
  255.      TESTFILE            
  256.      WAIT_BLIT           
  257.      BEAM_DELAY          
  258.      GETLVO              
  259.      WAIT_JOY            
  260.      WAIT_LMB            
  261.  
  262.      HDPARAMS            
  263.      SAVEOS_DATA         
  264.      SET_VARZONE         
  265.  
  266.      RELOC_MOVEL         
  267.      RELOC_MOVEW         
  268.      RELOC_MOVEB         
  269.      RELOC_CLRL          
  270.      RELOC_CLRW          
  271.      RELOC_CLRB          
  272.      RELOC_STL           
  273.      RELOC_STW           
  274.      RELOC_STB           
  275.      RELOC_TSTL          
  276.      RELOC_TSTW          
  277.      RELOC_TSTB          
  278.      RELOC_SUBL          
  279.      RELOC_SUBW          
  280.      RELOC_SUBB          
  281.      RELOC_ADDL          
  282.      RELOC_ADDW          
  283.      RELOC_ADDB          
  284.  
  285.      Using registers     
  286.  
  287.  
  288.  
  289.  
  290. JOTDStartup/STORE_REGS-RESTORE_REGS
  291.  
  292.  
  293. STORE_REGS
  294. Save all the registers to stack (D0 to A6)
  295.  
  296. RESTORE_REGS
  297. Restore all the registers from stack (D0 to A6)
  298.  
  299. No parametrers expected.
  300.  
  301.  
  302.  
  303.  
  304. JOTDStartup/Console output
  305.  
  306.  
  307. Mac_printf:
  308.  
  309. Prints messages with an easy syntax in an assembly program. Avoids label definition,
  310. and all the problems going with it.
  311.  
  312.     Mac_printf    "Hello world"
  313.     Mac_printf    "You are ",jkjdkfj
  314.     Mac_printf    "a hd-installer maniac"
  315.  
  316. will display on the console:
  317.  
  318. Hello world
  319. You are a hd-installer maniac
  320.  
  321. If you use 2 arguments in the macro, there will be no linefeed.
  322.  
  323.  
  324. PUTS:
  325.  
  326. Puts a string on the screen
  327. Argument: string pointer.
  328.  
  329. NEWLINE:
  330.  
  331. Just skips a line. No argument needed.
  332.  
  333.  
  334. Note: Those macros use the Display() routine.
  335.  
  336.  
  337.  
  338.  
  339. JOTDStartup/PatchMacros
  340.  
  341.  
  342. GETUSRADDR
  343. Returns in D0 the relocated address of a routine in the user code.
  344. This avoids a lea addr(pc),A0 then move.l A0,D0, but is not really useful anymore in
  345. the JST environnement.
  346.  
  347. GETGENADDR
  348. Returns (in D0) the address of a relocated general purpose routine.
  349.  
  350. Example:
  351.  
  352.     lea    $1456(A1),A0
  353.     GETGENADDR    ReadRobSectors
  354.     move.w    #$4EF9,(A0)+
  355.     move.l    D0,(A0)+
  356.  
  357. PATCHUSRJMP
  358. Sets a JMP to a given user relocatable address. The patched location is absolute.
  359. It may be used for chipmem, but not for extension mem, since you cannot know the
  360. absolute address (you have to calculate it). Do it by hand in this case.
  361.  
  362. PATCHUSRJSR
  363. Same thing, but with a JSR
  364.  
  365. PATCHABSJMP
  366. PATCHABSJSR
  367. Obsolete. Same thing as PATCHUSRJMP/JSR
  368.  
  369. PATCHGENJMP
  370. Sets a JMP in the general purpose relocated area (i.e. the functions of this
  371. library callable with JSRGEN)
  372.  
  373. PATCHGENJSR
  374. Same thing, for JSRs
  375.  
  376.  
  377.  
  378.  
  379. JOTDStartup/CallMacros
  380.  
  381.  
  382. JSRGEN
  383. JSRGEN_FREEZE
  384. JMPGEN
  385. Calls a relocated general purpose function.
  386.  
  387. E.g:    JSRGEN    TrackLoad
  388.  
  389. Those macros use A5 to get the function address. This register is restored.
  390.  
  391. JSRGEN_FREEZE can be useful if A5 (and also other registers used by the JST function)
  392. is used during interrupts.
  393. This macro freezes all the interrupts by setting SR to $2700 (means that
  394. you've got to be in superuser mode to use it), executes
  395. the function, then restores SR. I had to use it in Menace and Lotus Turbo Challenge.
  396.  
  397. JSRABS
  398. JMPABS
  399. Calls a absolute general purpose subroutine
  400.  
  401. E.g:    JSRABS    LoadDisks
  402.  
  403.  
  404.  
  405.  
  406. JOTDStartup/Compelling Macros
  407.  
  408.  
  409. Those macros are used in (almost) every loader.
  410.  
  411. GO_SUPERVISOR
  412. Calls the Supervisor exec routine and stores the userstack in a variable.No argument needed.
  413. Since v1.1d GO_SUPERVISOR can be called twice safely (there's a check for user mode)
  414.  
  415. SAVE_OSDATA
  416. Calls SaveOSData() with the chipmem you want to be saved.
  417. If you want to save 512K chipmem, type
  418.     SAVE_OSDATA    $80000
  419.  
  420. Passing $200000 to the function will allocate as much as chipmem possible, and
  421. mirror only the other parts (0-low boundary and high boundary-$200000)
  422.  
  423. If you want to save all the 2MB of chipmem:
  424.  
  425.     SAVE_OSDATA    $200000
  426.  
  427. This will allocate a big block of chipmem, and this block won't have to be mirrored.
  428.  
  429. Passing 2 arguments to SAVE_OSDATA will activate autoquit key feature.
  430. The 2nd argument is the autoquit key that you want to use (raw keycode)
  431.  
  432. Passing 3 arguments to SAVE_OSDATA will allow you to specify some custom user code
  433. you want called on exit (just like in SetExitRoutine())
  434. The 3rd argument is the address of the custom routine.
  435.  
  436. HD_PARAMS
  437. A compulsory macro which declares some variables, and also set tags for JST to read
  438. and write data and also recognize the loader.
  439.  
  440.     HD_PARAMS    "game.d",filesize,number of disks
  441.  
  442. The filesize can be set to STD_DISK_SIZE (901120) for normal trackload copiable disks.
  443. See the examples.
  444.  
  445. In diskfile mode, this call makes JST expect the diskfiles to be named game.d1, game.d2, etc...
  446. In files mode, the first argument allows to specify the subdir where the data files are
  447. to be located. (But you can also use SetFilesPath() to set the subdir too)
  448.  
  449. For a loader using files located in the same directory as the loader:
  450.  
  451.     HD_PARAMS    "",0,0
  452.  
  453.  
  454.  
  455. WARNING: This macro has 3 arguments. It's not possible to choose the window name any more.
  456. An error message will show up when assembling if you put the wrong number of arguments.
  457.  
  458. SET_VARZONE:
  459.  
  460. A macro useful in the case you want to add snapshot option to your loader and you've got local
  461. variables that you need to save in the loader (e.g. current disk unit, some flags...)
  462.  
  463. Put it everywhere you want. The best thing is to put it right after HD_PARAMS macro.
  464. The code will be executed even before your loader code.
  465.  
  466. This macro consists in a simple JSRABS SetLocalVarZone, with in A0 the start location of the
  467. variables (argument 1 of the macro) and in A1 the end location of the variables (argument 2
  468. of the macro).
  469.  
  470. All registers are preserved.
  471.  
  472. If you pass invalid values to this routine (e.g start after end) JST will tell it and quit.
  473.  
  474.  
  475.  
  476.  
  477. JOTDStartup/MiscMacros
  478.  
  479.  
  480. WAIT_LMB:
  481.  
  482. A simple left mouse button pause (port 0).
  483.  
  484. WAIT_JOY:
  485.  
  486. A simple joystick button pause (port 1).
  487.  
  488.  
  489. TESTFILE:
  490.  
  491. Calls the TestFile() function, with relocatable argument.
  492.  
  493.     TESTFILE    fname
  494.     tst.l    D0
  495.     bne    FileError
  496.  
  497. Actually this routine takes D0 as input and that's a bit annoying since in a relocatable
  498. environment we have to lea (pc) in an address register then move to D0 and call the routine.
  499. I don't want to change the way the routine works (backwards compatibility)
  500. but this little macro makes life easier.
  501.  
  502.  
  503. GETLVO:
  504.  
  505. A simple macro to get LVO offset in D0.
  506.  
  507. Example:  GETLVO   AvailMem   will return negative offset of AvailMem
  508.  
  509. Intended to use with SetFakeFunction()
  510.  
  511.  
  512. WAIT_BLIT
  513.  
  514. A macro to wait for the blitter operation to end (equivalent to WaitBlit
  515. but does not use any registers, useful for games which use/modify registers
  516. in interrupts)
  517.  
  518. BEAM_DELAY
  519.  
  520. A macro to wait using the vertical beam. Takes one argument.
  521.  
  522.     BEAM_DELAY    1
  523.  
  524. will wait approx. 20 ms (PAL)
  525.  
  526.  
  527.  
  528.  
  529.  
  530. JOTDStartup/Relocatable Memory operations
  531.  
  532.  
  533. RELOC_MOVEL/W/B:
  534.  
  535. A macro which allows to move some data in an address specified by a label, but in a relocatable
  536. way:
  537.  
  538.     move.l    D0,label    ; is not relocatable and JST will refuse it
  539.  
  540.     move.l    A6,-(sp)
  541.     lea    label(pc),A6
  542.     move.l    D0,(A6)        ; is relocatable. but a pain to write
  543.     move.l    (sp)+,A6
  544.  
  545. That's what RELOC_MOVEL does.
  546.  
  547. For Word and Byte format, similar macros known as RELOC_MOVEW and RELOC_MOVEB exist.
  548.  
  549. RELOC_TSTL/W/B:
  550.  
  551. With the 68020+ instruction set, it's possible to test a label in a relocatable way:
  552.  
  553.     tst.l    label(pc)
  554.  
  555. But with the 68000 this is not possible. So I made a useful macro:
  556.  
  557.     RELOC_TSTL    label
  558.  
  559.  
  560. RELOC_CLRL/W/B:
  561.  
  562. Makes a RELOC_MOVE/W/B #0 to location
  563.  
  564. RELOC_ADDL/W/B:
  565. RELOC_SUBL/W/B:
  566.  
  567. relocatable add/sub
  568.  
  569.  
  570.  
  571.  
  572. JOTDStartup/Registers: CAUTION!
  573.  
  574.  
  575. Be careful not to use registers A5 and A6 with some macros, because they
  576. often use those registers: e.g:
  577.  
  578.         PATCHUSRJMP     ($30,A5),PatchLoader
  579.     
  580. will crash because PATCHUSRJMP uses A5. This is subject to change, though.
  581. To change working registers (A5,A6) used in the macros to lets say (A3,A4),
  582. just include the following lines BEFORE the jst.i include.
  583.  
  584. REDEFINED_REGISTERS = 1    ; to tell jst.i that we've redefined the registers
  585. Ax EQUR A3        ; work register #1
  586. Ay EQUR A4        ; work register #2
  587.  
  588.  
  589. Or manually:
  590.  
  591.         move.l   A0,-(sp)
  592.         move.l   A5,A0
  593.         PATCHUSRJMP      ($30,A0),PatchLoader
  594.         move.l   (sp)+,A0
  595.  
  596.  
  597.  
  598.  
  599.  
  600. JOTDStartup/JoypadState()
  601.  
  602.  
  603. ULONG JoypadState(port)
  604.  D0                D0
  605.  
  606. This routine allows to check CD32 joypad buttons. It obviously does not use
  607. lowlevel.library and is buggy unless on a CD32 (why???). It's ripped from
  608. James Pond 3 routine (I was not the first since the ReadJoypad.s from aminet
  609. was also ripped from this one).
  610.  
  611. port can be 0 (mouse port) or 1 (joystick port).
  612.  
  613. The routine returns bits that you can test. The bits are defined in gp_macros.i
  614.  
  615.     moveq    #0,D0
  616.     JSRGEN    JoypadState
  617.     btst    #AFB_START    ; start/pause button
  618.     beq    nostart$
  619.     ...
  620.  
  621. On a normal amiga, you've got to go in a direction to make this routine work.
  622. I don't know why, but it works perfectly on a CD32.
  623. Also, you can't press fire (red button) and the other buttons together, or only fire
  624. will be detected.
  625.  
  626. You have to wait for a vertical blank to occur before you can use this function.
  627. I suggest that you put it in the level 3 interrupt, just before acknowledge
  628. (which is a move in $DFF09C) and set the flags here. Then another routine will
  629. check those flags and emulate game keys such as pause, jump/fire, etc... it's
  630. up to you :)
  631.  
  632. NOTE:
  633.  
  634. If you only want to check the second button (blue, or Sega joystick 2nd button),
  635. you can also read $DFF016 and check for bit 14 low, still after a VBLANK.
  636. Don't forget to reset the potgo in that case by
  637.  
  638.     move.w    #$CC01,($DFF034)
  639.  
  640. See also:
  641.  
  642.  
  643.  
  644.  
  645. JOTDStartup/GetUserData()
  646.  
  647.  
  648. APTR GetUserData(void)
  649.  A0
  650.  
  651. This routine returns in A0 a pointer to the NULL terminated string passed by
  652. the USERDATA argument or tooltype. It points to an empty string if USERDATA
  653. was not filled. It's useful to set a swith other than the user ones already present
  654. such as TRAINER, JOYPAD... and some info can be passed (it's not only a switch)
  655.  
  656. I used it in the Awesome JST ripper to specify the disk, side and drive unit.
  657.  
  658. See also: GetUserFlags()
  659.  
  660.  
  661.  
  662.  
  663. JOTDStartup/GetUserFlags()
  664.  
  665.  
  666. ULONG GetUserFlags(void) - returns loader set options
  667.  D0
  668.  
  669. This routine returns in D0 a combination of the option the user could have set.
  670. Not all the options are present here, only some switches which are:
  671.  
  672. TRAINER
  673. HDLOAD
  674. LOWMEM
  675. NTSC
  676. NOOSSWAP
  677. JOYPAD
  678.  
  679. To test if an option is active, just do a btst #AFB_<option>,D0 after having called
  680. GetUserFlags(). Example:
  681.  
  682.     JSRGEN    GetUserFlags
  683.     btst    #AFB_NTSC,D0
  684.     bne    .nontsc
  685.     
  686.     ; ntsc set
  687.     ; do stuff for NTSC ...
  688.  
  689. .nontsc
  690.  
  691.  
  692. See also: GetUserData()
  693.  
  694.  
  695.  
  696.  
  697. JOTDStartup/SetLocalVarZone()
  698.  
  699.  
  700. void SetLocalVarZone(start,end) - Sets saveable variable location in the loader
  701.                        A0  A1
  702.  
  703. When you make a snapshot, you save JST internal memory and the game internal memory,
  704. but you may also need to save some data relevant to your loader (e.g. current disk).
  705.  
  706. You may not need this routine if your loader is completely state-independent
  707. (i.e. does not require variables to work)
  708.  
  709. Extension memory pointer does not count as it's restored by the snapshot.
  710. No need to save this one.
  711.  
  712. Always call this routine before SAVE_OSDATA (or use the SET_VARZONE macro)
  713.  
  714. See also: InGameIconify, SET_VARZONE (macro)
  715.  
  716.  
  717.  
  718.  
  719. JOTDStartup/SetFilesPath()
  720.  
  721.  
  722. void SetFilesPath(dirname) - Changes default path for files to load to wished value
  723.                      A0
  724.  
  725. The first argument of HD_PARAMS can no longer be the subdir where the data files are
  726. to be loaded.
  727.  
  728. Use SetFilesPath instead. This function will change the load directory.
  729.  
  730. See also:
  731.  
  732.  
  733.  
  734.  
  735. JOTDStartup/UseHarryOSEmu()
  736.  
  737.  
  738. void UseHarryOSEmu(void) - allows the use of Harry's excellent OS emulation program
  739.  
  740. This function will allow you to use Harry's OS emulation program.
  741. This program must be called OSEmu.400 and be located in the C: directory.
  742.  
  743. This function allows a very powerful emulation, actually much better and complete
  744. than my OpenFakeExec() function!!
  745.  
  746. Read the documentation in the source code of OSEmu.asm for more details and refer
  747. to the JST loaders examples.
  748.  
  749. QUITKEY tooltype allows to change the default quit key (which is '*' of the numerical
  750. keyboard, provided that the keyboard is US/German. Actually this key is the upper right
  751. key of the numeric keypad, sorry A600 users :) )
  752.  
  753. See also: OpenFakeExec()
  754.  
  755.  
  756.  
  757.  
  758. JOTDStartup/DisableChipmemGap()
  759.  
  760.  
  761. void DisableChipmemGap(void) - deactivates gap in memory shadowing
  762.  
  763. When you call the macro SAVEOS_DATA with a maxchip value as argument,
  764. let's say for instance SAVEOS_DATA $80000, JST will allocate $80000 bytes
  765. of fastmem or chipmem (address above $80000 at all rates) to save the
  766. chipmem between $0 and $80000, and to swap it when the loader quits or
  767. swaps between game and OS (read/write data from HD...)
  768.  
  769. If the maxchip value is above $1FE000, JST does not normally allocate 2
  770. megabytes of fast memory because it's useless to waste that much memory,
  771. and uses AllocMem() on chipmem to allocate the largest chipmem block possible.
  772. This block being allocated, there's no need to save all the 2MB of memory but
  773. just below the lower bound of the allocated block and above the upper bound
  774. of the allocated block.
  775. But there's a technical problem here: when the loader reads/writes from the HD,
  776. it's rather hard to know where the data will be written/read from, because
  777. there's a gap which is not "shadowed", so I made this routine which forces JST
  778. to allocate 2 megabytes to save the chipmem, without the gap trick.
  779.  
  780. It costs more memory, but allows proper OS swap and data read/write.
  781.  
  782. This routine has no effect (at the moment) if the argument passed to SAVEOS_DATA
  783. is below $1FE000.
  784.  
  785. See also: SaveOSData()
  786.  
  787.  
  788.  
  789.  
  790. JOTDStartup/ReadUserDir()
  791.  
  792.  
  793. ULONG ReadUserDir(dirname, buffer, maxentries, maxnamelen) - Reads dir from the user dir
  794.  D0                 A0       A1       D0          D1
  795.  
  796. This function will read the files in the directory specified in A0. The SAVEDIR value
  797. will be concatenated in the path if SAVEDIR is provided in the tooltypes (OS 2.0+ only)
  798.  
  799. The filenames will be copied in the output buffer specified in A1.
  800. Please note that only the plain files will be copied. Directories will be ignored.
  801.  
  802. This function will return the number of plainfiles in the directory in D0.
  803.  
  804. maxentries will allow to limit the number of files to be copied. It will prevent a buffer
  805. overflow. Set it to 0 if you don't want any limit.
  806.  
  807. maxnamelen will allow to limit the filename length. Set it to 0 and the limit will be 20
  808. characters.
  809. The filenames will be NULL terminated in the buffer, and spaced by maxnamelen bytes, even
  810. if the filenames are not that long, to allow easy search in the buffer.
  811.  
  812. e.g set maxnamelen to 32 ($20), and call ReadUserDir. The buffer will look like:
  813.  
  814. $00: f i r s t _ f i l e0 *rubbish*
  815. $20: s e c o n d _ f i l e0 *rubbish*
  816. $40: t h i r d _ f i l e0 *rubbish*
  817.  
  818. and so on...
  819.  
  820. I found it more convenient than a buffer depending on the actual length of the filenames,
  821. because a simple MULU allows to access any filename.
  822.  
  823.  
  824. See also: InGameOSCall()
  825.  
  826.  
  827.  
  828.  
  829. JOTDStartup/SaveOSData()
  830.  
  831.  
  832. void SaveOSData(chipmem_size,memsave) - Saves chipmem and custom & cia registers...
  833.                      D0        D1
  834.  
  835. Usually called by the SAVE_OSDATA macro.
  836.  
  837. The most important routine of JST package. You've got to understand it
  838. fully if you want to make a clean loader.
  839.  
  840. Useful for debug purposes and to be able to quit the game and make in-game
  841. OS calls (read/write files)
  842.  
  843. The memsave parameter is only used when the chipmem_size is $200000
  844. (AGA game loaded). If set to 0, SaveOSData will alloc the bigger chipmem
  845. chunk as possible and will therefore not care about this part of memory,
  846. so the save buffer in fastmem will be a lot smaller than 2MB.
  847. If set to -1, all chipmem will be saved. If DEBUG is set, memsave
  848. will also be set to -1 and you'll need more memory.
  849.  
  850. To save 1024K of chipmem:
  851.  
  852.      SAVE_OSDATA     $100000
  853.  
  854. To save 2048K of chipmem, trying to reduce fast memory consumption:
  855.  
  856.      SAVE_OSDATA     $200000
  857.  
  858.  
  859. If no memory is available, the chipmem won't be saved, and it won't be possible
  860. to quit the game/to get debug information.
  861. As a side effect, this function disables all interrupts/DMA this way:
  862.  
  863.     lea      #$DFF000  
  864.     move.w   #$4000,intena(A6)
  865.     move.w   #$7FFF,intreq(A6)
  866.     move.w   #$4020,dmacon(A6)   ; also remove sprite DMA
  867.  
  868. This is necessary as the system could keep on modifying and restoring chipmem could
  869. crash the machine. If your game bootup does not like the interrupts to be disabled,
  870. reactivate necessary interrupts/dma yourself.
  871.  
  872. SAVING MEMORY FOR A 2MB CHIP GAME
  873.  
  874. (If you can avoid to use the full 2MB of chip do it)
  875.  
  876. Trying to save 2MB of chip will activate the memsave option.
  877. This option consists in allocating as much as chipmem as possible, to avoid
  878. to allocate a whole block of 2MB fastmem. The allocated chipmem can be trashed
  879. by the game, it will not corrupt the system.
  880.  
  881. Be careful when you read or write a file to hard disk, because data may not match
  882. (addresses are translated to the fastmem chip mirror during an OS swap
  883. and the gap caused by the memsave option can 'corrupt' data).
  884. If you plan to activate memsave and read/save files to HD, do the disk IO
  885. in a fastmem buffer rather than in chipmem, and transfer it later (that's
  886. why you can read the HDLOAD/LOWMEM flag in the user code)
  887.  
  888. With diskfiles, check and display an error message if LOWMEM is on, because of
  889. the same problem, but you can't be sure if the bigger load part the game can
  890. do at a time...
  891.  
  892. See also: GO_SUPERVISOR, InGameExit, InGameOSCall, ReadFileHD, WriteFileHD
  893.  
  894.  
  895.  
  896.  
  897. JOTDStartup/Reboot()
  898.  
  899.  
  900. Just reboots the computer (the OS must be active)
  901.  
  902.  
  903.  
  904.  
  905. JOTDStartup/AllocExtMem(), Alloc24BitMem()
  906.  
  907.  
  908. ULONG AllocExtMem(bytesize) - Allocates memory for expansion memory
  909. ULONG Alloc24BitMem(bytesize) - Allocates memory for expansion memory in 24 bit space
  910.  D0                 D0
  911.  
  912. Lots of games need more than the standard 512K of chip memory.
  913. They often do some tests to know where they can write (see the patch section
  914. in the guide).
  915. Sometimes it's better not to leave the game detect the expansion RAM itself.
  916. Using AllocExtMem, you'll allocate a block of 512K, 1024K or any size, and
  917. you'll keep it in mind until the game searches for memory. Patch the routine
  918. with the pointer you allocated and:
  919.  
  920. 1) You'll be sure the game uses fast memory
  921. 2) The quit option will be safe, which means the memory will not be corrupted
  922.    by the game.
  923.  
  924. You could do this allocation by hand but as you always quit by calling InGameExit(),
  925. you could not get control again to free the memory.
  926. AllocExtMem() stores the data useful for FreeMem, and InGameExit() tries to free
  927. the memory you allocated automatically.
  928.  
  929. If you select the NOFAST tooltype, the extension memory block to be returned
  930. will ALWAYS be $80000, and more chip memory will be saved when you call
  931. SaveOSData (no need to add). E.g:
  932.  
  933.         move.l        #$80000,D0
  934.         JSRABS        AllocExtMem
  935.         RELOC_MOVEL   D0,ExtBase   ; relocatable macro for move.l
  936.     
  937.     ...
  938.     
  939.     SAVE_OSDATA    $80000
  940.  
  941.     
  942. WARNING: Do not call this routine more than once, as the first allocated zone won't
  943. be freeable.
  944.  
  945. Alloc24BitMem is exactly the same function except that it will try to allocate memory
  946. with the 24BITDMA flag set (chip of 24 bit fastmem if you've got some). Useful for
  947. some games that don't like 32 bit fastmem (shitty coded).
  948.  
  949. Both will check that the beginning of the allocated block is above address $80000,
  950. and will return 0 if it's below.
  951.  
  952. See also: 
  953.  
  954.  
  955.  
  956.  
  957. JOTDStartup/OpenFakeExec()
  958.  
  959.  
  960. ULONG OpenFakeExec(void) - Create a exec-like function table
  961.  D0
  962.  
  963. This routine (new since V0.7 of JST) allocates $300 bytes and creates a function
  964. table that matches ExecBase offsets. Of course all calls are not emulated, and some
  965. are forbidden. For instance, you cannot OpenLibrary() (of course), or OpenDevice
  966. with device name different from "trackdisk.device".
  967.  
  968. To use only after SaveOSData. Fake ExecBase will be in $4.
  969. For the moment it does not support ExecBase structure. Only functions are supported.
  970.  
  971. This function table saves a lot of hassle because you don't have to insert BRA.B
  972. everywhere to skip those function calls.
  973.  
  974. Calls supported:
  975.  
  976. CacheClearU (flushes caches) 
  977. CacheClearE (flushes caches)
  978. CacheControl (flushes caches, returns 0 in D0 and D1)
  979. AllocAbs (returns the value in A1 in D0, as if absblock had been allocated)
  980. DoIO (calls TrackLoad(), as only trackdisk.device can be opened. Returns 0)
  981. OpenDevice (checks for "trackdisk.device", and then returns 0)
  982. FindTask (returns 0 in D0!!)
  983.  
  984. DoIO() is limited to commands 2 and 9. Write is not supported. If you want it to
  985. be, you have to overwrite the DoIO function with SetFakeFunction().
  986.  
  987. Inactivated calls:
  988.  
  989. Disable
  990. Enable
  991. Forbid
  992. Permit
  993. SuperState
  994. UserState
  995. AddPort
  996. RemPort
  997. CloseLibrary
  998. CloseDevice 
  999.  
  1000. Calling any of the above will only do a RTS
  1001.  
  1002. Unsupported calls:
  1003.  
  1004. OpenLibrary
  1005. OldOpenLibrary
  1006. AllocMem
  1007. FreeMem
  1008. AvailMem
  1009.  
  1010. Calling unsupported calls and other calls will trigger an runtime error.
  1011. The difference is that calling an unsupported call will display a specific message
  1012. (AllocMem not defined...) whereas other calls are not differentiated in the error
  1013. message (sorry you have to hunt for the offset)
  1014.  
  1015. Anyway, you can overwrite the system calls with the SetFakeFunction() call.
  1016. This way, you can define your own AllocMem(), etc...
  1017.  
  1018. If you succeed in defining some useful and cool routines, I'll be glad to integrate
  1019. them in JST default fakeexec emulation.
  1020.  
  1021. Return Values:
  1022.  
  1023. D0: 0 in any cases at the moment, but soon will return 0 if OK.
  1024.  
  1025. Note:
  1026.  
  1027. If DEADLY tooltype is on (DEADLY sets $FF000001 in ExecBase location to detect games
  1028. which use system calls besides other things), OpenFakeExec will display a warning.
  1029. DEADLY ExecBase kill will be deactivated.
  1030.  
  1031. Sometimes the game just reads in ExecBase to see the first block of fastmem, does calculations
  1032. on it with ANDs #$FFF80000 and so on. In this case you have to patch the routine by hand.
  1033. Just run the game from floppy or without OpenFakeExec or DEADLY to understand how it behaves,
  1034. and then copy the behaviour.
  1035. The best thing to do is to have a stock A500 with Action Replay. Then you can see exactly how
  1036. the game understands and stores the info for 512K chip and 512K fast.
  1037.  
  1038.  
  1039. See Also: SetFakeFunction(),TrackLoad()
  1040.  
  1041.  
  1042.  
  1043.  
  1044. JOTDStartup/FreezeAll()
  1045.  
  1046.  
  1047. void FreezeAll() - Freeze DMA and interrupts
  1048.  
  1049. Be sure to save the custom registers before with SaveCustomRegs.
  1050. This function is useful to start/stop a game without being annoyed
  1051. by ongoing DMA on interrupts.
  1052.  
  1053. See also: SaveCustomRegs(),RestoreCustomRegs()
  1054.  
  1055.  
  1056.  
  1057.  
  1058. JOTDStartup/LoadDisks()
  1059.  
  1060.  
  1061. void LoadDisks() - Load Disks in memory
  1062.  
  1063. Loads the disk from the HD_PARAMS macro parameters in the user program
  1064. no parameters are returned. The routine will exit with an error message
  1065. if something fails (no memory, file not found...)
  1066. else, it will return to the caller.
  1067.  
  1068. See also: LoadFiles(), LoadDiskFromName()
  1069.  
  1070.  
  1071.  
  1072.  
  1073. JOTDStartup/LoadDisksIndex()
  1074.  
  1075.  
  1076. void LoadDisksIndex(index) - Load Disks in memory, starting from index
  1077.                       D0
  1078.  
  1079. Same thing as LoadDisks(), but it begins at the disk number specified in D0
  1080.  
  1081. See also: LoadDisks(), LoadDiskFromName()
  1082.  
  1083.  
  1084.  
  1085.  
  1086. JOTDStartup/LoadDiskFromName()
  1087.  
  1088.  
  1089. void LoadDiskFromName(file name) - Load the file as a disk file
  1090.             D0
  1091.             
  1092. Loads the disk from the HD_PARAMS macro parameters in the user program,
  1093. but the name will be ignored and replaced by the one you mention.
  1094. no parameters are returned. The routine will exit with an error message
  1095. if something fails (no memory, file not found...)
  1096. else, it will return to the caller.
  1097.  
  1098. If you call it twice, first file will be disk 0 and second will be disk 1.
  1099.  
  1100. See also: LoadDisks(), LoadFiles()
  1101.  
  1102.  
  1103.  
  1104.  
  1105. JOTDStartup/LoadSmallFiles()
  1106.  
  1107.  
  1108. void LoadSmallFiles(size_limit) - Load small files in the current directory
  1109.                       D0
  1110.                       
  1111. This function will load all the files which length is inferior to
  1112. size_limit. The other ones will be loaded during game, but it is
  1113. transparent to the programmer because the ReadFile() function will
  1114. read either from preloaded files or from hard disk if the file is
  1115. too big to have been cached.
  1116. You'll understand that you'll have to adjust properly size_limit
  1117. depending on the game you're patching. If a game directory holds
  1118. 30 files of 1000 bytes each, and some big files (>50Ko)
  1119. you should set size_limit over 1000 else the ReadFileHD will be
  1120. called very often and as OS swaps take time and blackout the display,
  1121. your loader won't use properly the HDLOAD feature.
  1122.  
  1123. NOTE: If HDLOAD is not set, this function will behave exactly as
  1124. LoadFiles(), and will read all the files (no size limit)
  1125.                       
  1126. See also: LoadDisks(), LoadFiles(), ReadFile()
  1127.  
  1128.  
  1129.  
  1130.  
  1131. JOTDStartup/LoadFiles()
  1132.  
  1133.  
  1134. void LoadFiles() - Load all the files in the current directory
  1135.  
  1136.  
  1137. This function will perform a Lock() in the current directory, then will
  1138. create the structures to store the files and read them all in memory.
  1139. It does not load subdirectories. Only flat files will be read, so be
  1140. careful with games storing data in subdirectories. The installation
  1141. procedure will have to flatten the file structure.
  1142.  
  1143. This function will exit with an error message if an error occurs
  1144. else, it will return to the caller
  1145.  
  1146. See also: LoadSmallFiles(),LoadDisks(),ReadFileFast(),LoadRNCFile().
  1147.  
  1148.  
  1149.  
  1150.  
  1151. JOTDStartup/GetFileLength()
  1152.  
  1153.  
  1154. ULONG GetFileLength(filename) - Gets the length (bytes) of a file
  1155.   D0                   D0
  1156.  
  1157. This function returns the length of a file in bytes. If the file is not found,
  1158. it will return -1, so be careful to test the value.
  1159.  
  1160. This function can only be called when the OS is active (not during game,
  1161. or if you must do so, do it within a InGameOSCall).
  1162.  
  1163. See also: ReadFile()
  1164.  
  1165.  
  1166.  
  1167.  
  1168. JOTDStartup/TestFile()
  1169.  
  1170.  
  1171. ULONG TestFile(filename) - Tests if a file exists on the hard drive
  1172.   D0               D0
  1173.  
  1174.  
  1175. This function returns 0 if the specified filename exists (relative path
  1176. from JST path)
  1177.  
  1178. See also: TestFileAbs
  1179.  
  1180.  
  1181.  
  1182.  
  1183. JOTDStartup/TestFileAbs()
  1184.  
  1185.  
  1186. ULONG TestFileAbs(filename) - Tests if a file exists on the hard drive
  1187.   D0               D0
  1188.  
  1189.  
  1190. This function returns 0 if the specified filename exists (absolute path)
  1191.  
  1192. See also: TestFileAbs
  1193.  
  1194.  
  1195.  
  1196.  
  1197. JOTDStartup/LoadRNCFile()
  1198.  
  1199.  
  1200. ULONG LoadRNCFile(filename) - Loads and decrunches a RNC file from the Hard Drive.
  1201.  D0/A0/D1            D0
  1202.  
  1203. This function loads a file and decrunches it, allocating memory at the same time for the
  1204. decrunched length.
  1205. Return values: D0: error flag (0 if OK)
  1206.                A0: beginning of allocated buffer
  1207.                D1: allocated length (useful if the file space must be freed with FreeMem())
  1208.  
  1209. See also - RNCDecrunch(), RNCLength()
  1210.  
  1211.  
  1212.  
  1213.  
  1214. JOTDStartup/TransfRoutines()
  1215.  
  1216.  
  1217. void TransfRoutines(void) - (obsolete)
  1218.  
  1219. This routine is obsolete and provided only for compatibility reasons.
  1220. It does strictly nothing.
  1221.  
  1222. See also: 
  1223.  
  1224.  
  1225.  
  1226.  
  1227. JOTDStartup/BlockFastMem()
  1228.  
  1229.  
  1230. void BlockFastMem(sparemem) - Blocks fastmem
  1231.                       D0
  1232.  
  1233. D0 is the number of bytes to leave unallocated (roughly, not accurate).
  1234. 0 in D0 means the routine will try to allocate all fast memory available.
  1235.  
  1236. This is useful for some games which want chipmem but forget to specify it
  1237. in AllocMem() (old games), and also for games which do not like memory
  1238. located over $FFFFFF (coded in 32 bits).
  1239.  
  1240. Do not use it if not necessary (impossible to return to the OS
  1241. after that). You can use it when the TUDE NOFASTMEMORY BOOT=HIGHCHIP
  1242. is necessary to boot the wanted game from floppy without problems
  1243. TUDE is copyright N.O.M.A.D 1995. It can be found on aminet.
  1244.  
  1245. Normally if you track the game memory allocation, you should not use this
  1246. routine. Force the game to allocate its extension memory block in chipmem
  1247. (provided you've got 1MB chip, see BodyBlows patch).
  1248.  
  1249. See also: Degrade(), DegradeCpu().
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255. JOTDStartup/Degrade()
  1256.  
  1257.  
  1258. void Degrade(cacheset,cachemask) - Degrades everything to run games properly
  1259.                 D0       D1
  1260.  
  1261. This routine is a combination of both DegradeCpu() and DegradeGfx() routines.
  1262. Call it just before saving OS data and booting the game.
  1263.  
  1264. A classic sequence is:
  1265.  
  1266.     moveq    #0,D0
  1267.     move.l    #CACRF_CopyBack,D1
  1268.     JSRABS    Degrade            ; leave only instruction cache
  1269.     
  1270.     GO_SUPERVISOR
  1271.     SAVE_OSDATA    $80000
  1272.     
  1273.     .. boot stuff
  1274.     
  1275.     
  1276. See also: BlockFastMem(), DegradeCpu(), DegradeGfx(), Enhance()
  1277.  
  1278.  
  1279.  
  1280.  
  1281. JOTDStartup/Enhance()
  1282.  
  1283.  
  1284. Resets system enhancements (VBR, caches, gfx...)
  1285.  
  1286. This function should *NEVER* be called when using the library, but it could be
  1287. useful to call it to see what happens in an OS swap that fails. It's a function
  1288. that can be used in the standalone degrade code I've written
  1289.  
  1290. See also: Degrade()
  1291.  
  1292.  
  1293.  
  1294.  
  1295. JOTDStartup/DegradeGfx()
  1296.  
  1297.  
  1298. void DegradeGfx() - Degrades graphics to run games properly
  1299.  
  1300. This routine degrades the display using LoadView(NULL), and can set PAL or NTSC (tooltype).
  1301. It also opens an intuition screen if possible.
  1302.  
  1303.  
  1304. See also: BlockFastMem(), DegradeCpu(), Degrade()
  1305.  
  1306.  
  1307.  
  1308.  
  1309. JOTDStartup/DegradeCpu()
  1310.  
  1311.  
  1312. DegradeCpu(cacheset,cachemask) - Degrades only cpu related hardware
  1313.                 D0       D1
  1314.  
  1315. This routine does the following:
  1316.  
  1317. - It sets the VBR to $0 for 68010 and higher cpus unless the LEAVEVBR tooltype is present.
  1318. - It removes the specific 68060 caches (branch, writeallocate, and also the data/copyback
  1319.   cache, this last one the CacheControl() function leaves alone, even if you want to disable
  1320.   CopyBack)
  1321. - If NOCACHES is activated in the tooltypes, it will disable ALL caches.
  1322.  
  1323. The cacheset and cachemask variables are the same as in exec CacheControl().
  1324. Refer to the CacheControl autodoc for more details.
  1325.  
  1326. This function does not affect graphics modes at all.
  1327.  
  1328. See also: Degrade(), DegradeGfx()
  1329.  
  1330.  
  1331.  
  1332.  
  1333. JOTDStartup/Display()
  1334.  
  1335.  
  1336. void Display(message pointer) - Displays a message in the opened console or CLI
  1337.                A1
  1338.  
  1339. This function is generally called from the Mac_printf macro. This is more convenient,
  1340. but we may need to call it directly in some special cases.
  1341. If the program has been run from CLI, Display() will write in the CLI. If run from
  1342. workbench, it will write in the window opened by the startup program (see HD_PARAMS macro).
  1343.  
  1344. If no window exists, this function will do nothing (it won't even crash).
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350. JOTDStartup/CloseAllQuiet()
  1351.  
  1352.  
  1353. void CloseAllQuiet(void) - Frees everything and exits
  1354.  
  1355.  
  1356. This function frees all the memory allocated by the program (diskfiles, files, relocatable
  1357. code, windows) and quits the program. If you allocated memory from the user program
  1358. by using directly Exec routines, you'll have to free it before calling this function.
  1359. This function cannot be called when the game is running (the OS is killed). Call InGameExit
  1360. instead.
  1361. This function will exit at once, and the window will be closed if the program was started
  1362. from Workbench.
  1363.  
  1364. See also: InGameExit(), CloseAllQuiet()
  1365.  
  1366.  
  1367.  
  1368.  
  1369. JOTDStartup/CloseAll()
  1370.  
  1371.  
  1372. void CloseAll(void) - Frees everything and exits because of an error
  1373.  
  1374.  
  1375. This function frees all the memory allocated by the program (diskfiles, files, relocatable
  1376. code, windows) and quits the program. If you allocated memory from the user program, you'll
  1377. have to free it before calling this function.
  1378. This function cannot be called when the game is running (the OS is killed). Call InGameExit
  1379. instead.
  1380.  
  1381. If the program has been run from workbench, it will ask for the RETURN key before closing
  1382. the console, in order for you to see what went wrong.
  1383.  
  1384. See also: InGameExit(), CloseAllQuiet()
  1385.  
  1386.  
  1387.  
  1388.  
  1389. JOTDStartup/FlushCachesSys()
  1390.  
  1391.  
  1392. void FlushCachesSys(void) - Flushes the caches using OS calls
  1393.  
  1394. Well, this function calls CacheControl(0L,0L), and the caches are flushed.
  1395.  
  1396. See also: FlushCachesHard(),Degrade()
  1397.  
  1398.  
  1399.  
  1400.  
  1401. JOTDStartup/GetMemFlag()
  1402.  
  1403.  
  1404. ULONG GetMemFlag(void) - Return MEMF_REVERSE if kick 39+
  1405.  D1
  1406.  
  1407. As the MEMF_REVERSE flag (AllocMem, AllocVec) does not exist in KS 1.x, and was broken
  1408. until V39, this function checks for the kick version, and returns 0 if it is too old.
  1409. Else, it will return MEMF_REVERSE.
  1410.  
  1411. That will explain that JST loaders will have more chances to work on V39 machines.
  1412.  
  1413.  
  1414.  
  1415.  
  1416. JOTDStartup/TestxMbChip()
  1417.  
  1418.  
  1419. ULONG Test1MBChip() - Hardware test for 1MB chip memory
  1420. ULONG Test2MBChip() - Hardware test for 2MB chip memory
  1421.  
  1422. This routine Test1MBChip (resp Test2MBChip) pokes in the location $80000 (resp $100000),
  1423. then checks for location $0. If they are the same, then chipmem is 512K
  1424. (resp 1024K or 512K) ,else, it's at least 1024K (resp 2048K)
  1425. This routine is safe. It calls Disable and restores the altered chip locations.
  1426. Returns 0 if chipmem is as required (>1024K resp 2048K), -1 else.
  1427.  
  1428. NOTE: To test for 512K chip, use Test1MBChip. To check for 1MB chip, use
  1429. Test1MBChip, then Test2MBChip to know if it's only 1024K or 2048K.
  1430. I don't think further amigas (if there any) will have more than 2MB of chipmem...
  1431. Also notice that some computers have 2MB of chipmem and are not AGA, and
  1432. that some so-called AGA games only assume you've got 2MB of chip and can
  1433. be run on 2MB chip ECS amigas or even on 512K OCS amigas (but in that last
  1434. case you'll have to relocate some code heavily!!)
  1435.  
  1436. Example: Jungle Strike AGA (Ocean) runs fine on UAE with 2MB of chipmem.
  1437.  
  1438.  
  1439. See also: CheckAGA()
  1440.  
  1441.  
  1442.  
  1443.  
  1444. JOTDStartup/CheckAGA()
  1445.  
  1446.  
  1447. ULONG CheckAGA(void) - Checks DeniseID to see if the computer supports AGA or not
  1448.   D0
  1449.  
  1450. This function will return 0.L in D0 if AGA is supported, -1.L else.
  1451.  
  1452.  
  1453.  
  1454.  
  1455. JOTDStartup/GetSR()
  1456.  
  1457.  
  1458. UWORD   GetSR() - Returns CPU status register
  1459.  D0          
  1460.                   
  1461. SR will be copied in D0. No need to be in suprevisor mode to call
  1462. this function (or else it has no interest).
  1463.  
  1464. See also:
  1465.  
  1466.  
  1467.  
  1468.  
  1469. JOTDStartup/GetAttnFlags()
  1470.  
  1471.  
  1472. UWORD   GetAttnFlags() - Returns CPU AttnFlags while OS is down
  1473.  D0          
  1474.                   
  1475. At startup, exec's AttnFlags is copied and relocated. So if you need
  1476. to know something about the CPU you patch is running on, use this
  1477. function. You can test the bits like a normal CPU bit test.
  1478.  
  1479. See also:
  1480.  
  1481.  
  1482.  
  1483.  
  1484. JOTDStartup/WriteFileHD()
  1485.  
  1486.  
  1487.        WriteFileHD(command,length,name,buffer) - Writes a file to disk during game
  1488. D0,D1                D0(=0)   D1    A0    A1
  1489.                   
  1490. This function is very useful to write some data from disk on demand during
  1491. the game for savegame data files or hiscores.
  1492.  
  1493. D0.L: command: leave to 0 for the moment
  1494. D1.L: length in bytes (be careful!!)
  1495. A0:   pointer on the name, NULL terminated
  1496. A1:   source data buffer (either in fastmem or chipmem)
  1497.  
  1498.  
  1499. Note: as the game chipmem is transfered to a fastmem area during OS calls,
  1500. if you load a file into a chipmem zone, it will be loaded in the fastmem
  1501. mirror instead, and will appear in chipmem after the OS is killed again,
  1502. so don't worry about that (except if you save 2MB chip and activate memsave).
  1503.  
  1504. The function returns D0=0 on success, -1 else.
  1505. If success, D1.L contains the length actually written.
  1506.  
  1507.  
  1508. You can call this function whether the OS is alive or not.
  1509.  
  1510.  
  1511. If you want to write user data (like scores or gamesaves), you'd better use WriteUserFileHD()
  1512. because this function uses SAVEDIR parameter to write data to another directory in the
  1513. registered version of JST.
  1514.  
  1515. See also: InGameOSCall(), WriteUserFileHD().
  1516.  
  1517.  
  1518.  
  1519. JOTDStartup/WriteUserFileHD()
  1520.  
  1521.  
  1522.        WriteUserFileHD(command,length,name,buffer) - Writes a file to disk during game in SAVEDIR
  1523. D0,D1                   D0(=0)   D1    A0    A1
  1524.  
  1525.  
  1526. Same thing as WriteFileHD, except that if SAVEDIR tooltype is set, (SAVEDIR-RAM:), the data
  1527. will be saved here, and not in the game directory. Useful for write only/copyback cached
  1528. partitions.
  1529.  
  1530. See also: WriteFileHD(), ReadUserFileHD().
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536. JOTDStartup/ReadUserFileHD()
  1537.  
  1538.  
  1539.        ReadUserFileHD(command,length,name,buffer) - Reads a file to disk during game in SAVEDIR
  1540. D0,D1                  D0(=0)   D1    A0    A1
  1541.  
  1542.  
  1543. Same thing as ReadFileHD, except that if SAVEDIR tooltype is set, (SAVEDIR-RAM:), the data
  1544. will be saved here, and not in the game directory.
  1545.  
  1546. See also: ReadFileHD(), WriteUserFileHD().
  1547.  
  1548.  
  1549.  
  1550.  
  1551. JOTDStartup/ReadFile()
  1552.  
  1553.  
  1554.       ReadFile(command,length,name,buffer) - Reads a file from disk/RAM during game
  1555. D0,D1           D0(=0)   D1    A0    A1
  1556.  
  1557. This command is very similar to ReadFileHD() except that it will
  1558. check if the file was not cached in memory first.
  1559.  
  1560. In the case HDLOAD/LOWMEM is on, it will often read files from HD. If those flags are off,
  1561. all the files will be loaded from memory because they had been preloaded
  1562. (by LoadFiles() or LoadSmallFiles()).
  1563.  
  1564. See also: ReadFileHD(),ReadFilePart().
  1565.  
  1566.  
  1567.  
  1568.  
  1569. JOTDStartup/ReadFilePart()
  1570.  
  1571.  
  1572.       ReadFilePart(command,length,offset,name,buffer) - Reads a part of a file from disk/RAM during game
  1573. D0,D1               D0(=0)   D1     D2    A0    A1
  1574.  
  1575. This command is very similar to ReadFilePartHD() except that it will
  1576. check if the file was not cached in memory first.
  1577.  
  1578. In the case HDLOAD/LOWMEM is on, it will often read files from HD. If those flags are off,
  1579. all the files will be loaded from memory because they had been preloaded
  1580. (by LoadFiles() or LoadSmallFiles()).
  1581.  
  1582. See also: ReadFileHD(),ReadFilePartHD().
  1583.  
  1584.  
  1585.  
  1586.  
  1587. JOTDStartup/ReadFilePartHD()
  1588.  
  1589.  
  1590.       ReadFilePartHD(command,length,offset,name,buffer) - Reads a part of a file from disk/RAM during game
  1591. D0,D1                 D0(=0)   D1     D2    A0    A1
  1592.  
  1593. This function will try to load a part of a file from HD.
  1594.  
  1595. D0: 0 if OK
  1596. D1: length read in bytes
  1597.  
  1598. See also: ReadFileHD(),ReadFilePart().
  1599.  
  1600.  
  1601.  
  1602.  
  1603. JOTDStartup/ReadFileHD()
  1604.  
  1605.  
  1606.       ReadFileHD(command,length,name,buffer) - Reads a file from disk during game
  1607. D0,D1             D0       D1    A0    A1
  1608.                   
  1609. This function is very useful to read some data from disk on demand during
  1610. the game. It can load the game files or savegame data files.
  1611.  
  1612. D0: command: 0: normal operation, $FF reserved. Leave to zero at the moment
  1613. D1: length in bytes. -1 means all the file
  1614. A0: pointer on the name, NULL terminated
  1615. A1: destination data buffer (either in fastmem or chipmem)
  1616.  
  1617. Note: as the game chipmem is transfered to a fastmem area during OS calls,
  1618. if you load a file into a chipmem zone, it will be loaded in the fastmem
  1619. mirror instead, and will appear in chipmem after the OS is killed again,
  1620. so don't worry about that (except if you save 2MB chip, in that case,
  1621. I allocate chipmem to save some fastmem, so there's a gap!!)
  1622.  
  1623. The function returns D0=0 on success, -1 else.
  1624. If success, D1.L contains the length actually read.
  1625.  
  1626. You can call this function whether the OS is alive or not.
  1627.  
  1628. This function will not check for cached file in memory. Calling ReadFileHD forces
  1629. a read from HD (an OS swap is necessary). If you don't know if the file was cached or
  1630. not, use ReadFile() instead.
  1631.  
  1632. If you want to read user data (like scores or gamesaves), you'd better use ReadUserFileHD()
  1633. because this function uses SAVEDIR parameter to read data from another directory in the
  1634. registered version of JST.
  1635.  
  1636. See also: ReadFile(), InGameOSCall(), WriteFileHD(), DeleteFileHD(), ReadUserFileHD().
  1637.  
  1638.  
  1639.  
  1640.  
  1641. JOTDStartup/DeleteFileHD()
  1642.  
  1643.  
  1644. ULONG DeleteFileHD(name) - Deletes a file from disk during game
  1645.  D0                 A0
  1646.  
  1647. This can also be done by calling InGameOSCall() but I needed it in the
  1648. Sensible Golf patch and then I included this function in the library.
  1649.  
  1650. Will return 0 if success, -1 else.
  1651.  
  1652. You can call this function whether the OS is alive or not.
  1653.  
  1654. If you want to delete user data (like scores or gamesaves), you'd better use DeleteUserFileHD()
  1655. because this function uses SAVEDIR parameter to delete data from another directory in the
  1656. registered version of JST.
  1657.  
  1658. See also: InGameOSCall(), ReadFileHD(), WriteFileHD(), DeleteUserFileHD()
  1659.  
  1660.  
  1661.  
  1662.  
  1663. JOTDStartup/DeleteUserFileHD()
  1664.  
  1665.  
  1666. ULONG DeleteUserFileHD(name) - Deletes a file from disk during game in SAVEDIR
  1667.  D0                     A0
  1668.  
  1669. Same routine as DeleteFileHD(), but uses SAVEDIR if set to search file to delete
  1670. into. Unvaluable because cannot be reproduced using InGameOSCall() (because
  1671. for the moment it's not possible to get SAVEDIR value from the object)
  1672.  
  1673.  
  1674. See also: InGameOSCall(), ReadFileHD(), WriteFileHD(), DeleteUserFileHD()
  1675.  
  1676.  
  1677.  
  1678.  
  1679. JOTDStartup/InGameOSCall()
  1680.  
  1681.  
  1682. ULONG InGameOSCall(entrypoint) - Calls a routine containing OS code
  1683.                        A4
  1684.  
  1685. This is one of the most powerful and also one of the most dangerous function of
  1686. this package.
  1687. It allows the user to call a program using normal system calls, while the game
  1688. has totally destroyed the OS.
  1689. It restores the OS and interrupts and saves the game memory, goes in user mode, calls
  1690. the user routine, and restores everything for the game.
  1691. The display goes black because this is not possible to save the colormap and other
  1692. screen data.
  1693. The user routine can trash all the registers. They're saved and restored after the call.
  1694.  
  1695. However, there are problems with this routine:
  1696.  
  1697. - Any Write() made to disk may not terminate when the game is re-activated. So
  1698.   you'll better disable disk caches and quit the game correctly after that.
  1699.   If someone knows how to wait for the disk activity to finish, please call me.
  1700.   The problem that may occur is a devalidation of the disk (not very important).
  1701.   I use the dos Delay() command after the write operation with 2 seconds, and it works:
  1702.  
  1703.     move.l    #100,D1
  1704.     move.l    _DosBase(pc),A6
  1705.     JSRLIB    Delay
  1706.  
  1707. - Playing with the keyboard while the disk is writing or reading locks the system.
  1708.   I don't know where it comes from, but I'll find out. For the moment, avoid to press
  1709.   any key during disk accesses (especially writes, this can lead to write errors !!!)
  1710.  
  1711. Besides those problems this routine is the only way to make real hard disk versions of games
  1712. which load and save data to disk.
  1713. Lots of the patches I've written use this routine. It took me some time for it to be reliable.
  1714. Some users still have problems. I'm improving it from time to time.
  1715.  
  1716.  
  1717. This routine returns 0 when the routine has been called, and -1 if the routine has not been
  1718. called because of the impossibility to save/restore the operating system, so be careful for
  1719. users without too much memory...
  1720.  
  1721. The register D0 you'll set in the OS routine will be passed to your program. It must be coherent
  1722. with the error code. E.g: if everything is OK, return 0, else return -1, or -2 to make a difference
  1723. with the OS switching error.
  1724.  
  1725. Example:
  1726.  
  1727. LoadScoreFile:
  1728.     lea    scorename(pc),A0
  1729.     move.l    A0,D1
  1730.     move.l    #MODE_OLDFILE,D2
  1731.     move.l    _SysBase(pc),A6
  1732.     JSRLIB    Open
  1733.     tst.l    D0
  1734.     beq    error$
  1735.  
  1736.     ...    ; do our stuff (reading...)
  1737.  
  1738.     JSRLIB    Close
  1739.     moveq.l    #0,D0
  1740.     rts
  1741. error$
  1742.     moveq.l    #-2,D0    ; file error code
  1743.     rts
  1744.  
  1745. LoadHighscores:
  1746.     lea    LoadScoreFile(pc),A4
  1747.     JSRGEN    InGameOSCall
  1748.     tst.l    D0
  1749.     beq    ok$        ; all is OK
  1750.     cmp.l    #-1,D0
  1751.     beq    oserr$        ; os could not be restored
  1752.                 ; else file error
  1753.  
  1754. I recently added the ReadFileHD() and WriteFileHD() routines, and this
  1755. routine is not to be used in most cases, but sometimes it's compulsory
  1756. (for instance listing a savegame directory during the game (Cannon Fodder 2))
  1757.  
  1758.  
  1759. IMPORTANT: This function will do nothing if the NOOSSWAP tooltype/argument is activated. To check
  1760. this argument, the register D1 will be set (-1.L) when _loader is called (beginning of the user
  1761. code).
  1762.  
  1763. See also: ReadFileHD(), WriteFileHD(), DeleteFileHD(), InGameExit()
  1764.  
  1765.  
  1766.  
  1767.  
  1768. JOTDStartup/PatchExceptions()
  1769.  
  1770.  
  1771. void PatchExceptions(void) - redirect system exceptions to custom routines
  1772.  
  1773.  
  1774. This routine allows to trap the following processor exceptions:
  1775.  
  1776. - Bus error
  1777. - Address error
  1778. - Illegal instruction
  1779. - Division by zero
  1780. - LINEA emulation
  1781. - LINEF emulation
  1782. - Format error
  1783. - some others... (subject to change)
  1784.  
  1785. PatchExceptions() is called at startup, so there's no need to do it by hand
  1786. normally, but it may be necessary to call it again in the user program in the
  1787. case of the game overwriting the values, and then crashes. That's why this function
  1788. is callable from user program.
  1789.  
  1790. When an exception is encountered, the handler returns to the OS with the 'exception
  1791. occured' or 'linef/movep (060)' message. If you want more information, use the DEBUG
  1792. tooltype or argument when running the loader, and a memory image of the game,
  1793. the registers an some other information will be written to disk. With the memory
  1794. and the stack value, maybe you're able to track the error or find out problems using
  1795. memory dump.
  1796.  
  1797. See Also:
  1798.  
  1799.  
  1800.  
  1801.  
  1802. JOTDStartup/FlushCachesHard()
  1803.  
  1804.  
  1805. void FlushCachesHard(void) - Flushes the caches
  1806.  
  1807. This routine is *VERY* useful to flush the caches when the OS is overridden
  1808. by the game, and you still want to use fast memory with the caches on.
  1809. It addresses CACR register to invalidate instruction and data caches,
  1810. and it also calls CPUSH to flush the copyback data cache into memory
  1811. (for 68040/68060) caches.
  1812.  
  1813.  
  1814. NOTE: As long as the OS is alive, use FlushCachesSys() whenever possible.
  1815.  
  1816. See also: FlushCachesSys()
  1817.  
  1818.  
  1819.  
  1820.  
  1821. JOTDStartup/GoECS()
  1822.  
  1823.  
  1824. void GoECS(void) - degrades display and sprites to ECS
  1825.  
  1826. This function is very useful when you start the loader from a multiscan screen with
  1827. a hires pointer. In that case, if the game uses sprites, they all appear shrinked,
  1828. as the game did not switch in lores pointer. 
  1829. It modifies the value of FMODE (set to 0) and BPLCON3 (set to $0C20).
  1830. This acts also on dual playfield parameters.
  1831.  
  1832. NOTE: This function will have no effect if the system copperlists are still active,
  1833. as they reset BPLCON3 every screen scan. Use it in an early stage of the game loader.
  1834. Look at the examples provided.
  1835.  
  1836. GoECS() is just a call to ResetDisplay() followed by a call to ResetSprites().
  1837.  
  1838. See also: ResetDisplay(), ResetSprites()
  1839.  
  1840.  
  1841.  
  1842.  
  1843. JOTDStartup/ResetDisplay()
  1844.  
  1845.  
  1846. void ResetDisplay(void) - Resets 15KHz display
  1847.  
  1848. This function avoids to get a modulo/AGA display problem.
  1849.  
  1850. NOTE: This function will have no effect if the system copperlists are still active,
  1851. as they reset BPLCON3 every screen scan. Use it in an early stage of the game loader.
  1852. Look at the examples provided.
  1853.  
  1854. See also: GoECS(), ResetSprites()
  1855.  
  1856.  
  1857.  
  1858.  
  1859. JOTDStartup/ResetSprites()
  1860.  
  1861.  
  1862. void ResetSprites(void) - Resets LORES sprites
  1863.  
  1864.  
  1865. If the sprites are too small vertically, call this function.
  1866.  
  1867. NOTE: This function will have no effect if the system copperlists are still active,
  1868. as they reset BPLCON3 every screen scan. Use it in an early stage of the game loader.
  1869. Look at the examples provided.
  1870.  
  1871. See also: GoECS(), ResetDisplay()
  1872.  
  1873.  
  1874.  
  1875.  
  1876. JOTDStartup/KickVerTest()
  1877.  
  1878.  
  1879. ULONG KickVerTest(kickversion) - Test if ROM version is newer than a given version
  1880.  D0                    D0
  1881.  
  1882. KickVerTest() uses the SoftVer variable in the ExecBase structure to test the
  1883. kickstart version.
  1884.  
  1885. kickversion is the kickstart version number (for instance 35,36,39...)
  1886. The function will return 0 is the installed version is newer than the wanted version
  1887. and -1 if not.
  1888.  
  1889. See also: Kick37Test()
  1890.  
  1891.  
  1892.  
  1893.  
  1894. JOTDStartup/Kick37Test()
  1895.  
  1896.  
  1897. ULONG Kick37Test(void) - Test if ROM is V37 or newer
  1898.  D0
  1899.  
  1900. The same thing as KickVerTest(), but compares the version to V37 (matches Workbench 2.0).
  1901. Useful when you don't know if you can use 2.0 features.
  1902.  
  1903. Returns D0=0  if KS>36, D0!=0 if KS<=36
  1904.  
  1905. See also: KickVerTest()
  1906.  
  1907.  
  1908.  
  1909.  
  1910. JOTDStartup/InitTrackDisk()
  1911.  
  1912.  
  1913. void InitTrackDisk(void) - Initialize trackdisk.device emulation
  1914.  
  1915. Call this when you need to emulate a DoIO(), very frequent in the bootblock of
  1916. games, which use trackdisk.device to load their loading routines, then forget
  1917. it along with the remainder of the system.
  1918. When you re-source the bootblock, replace all the JSRLIB DoIO by JSRGEN TrackLoadFast.
  1919. Before jumping to the bootblock code, you MUST call InitTrackDisk (use JSRGEN too),
  1920. or else the loads will be done anywhere in the memory -> GURU.
  1921. Refer to the examples for more details.
  1922.  
  1923. See also: TrackLoadFast(),SetTDUnit(),ReadRobSectorsFast()
  1924.  
  1925.  
  1926.  
  1927.  
  1928. JOTDStartup/TrackLoad
  1929.  
  1930.  
  1931. void TrackLoad(void) - Replaces DoIO function to read from a virtual floppy
  1932.  
  1933. This function replaces TrackLoadFast. It has the same function, but is able to
  1934. read from HD when LOWMEM is activated.
  1935.  
  1936. This function replaces the DoIO() function in the case of a floppy disk.
  1937. Once initialized with InitTrackDisk() and possibly with SetTDUnit(), you are
  1938. able to read sectors from the virtual floppy device exactly with the trackdisk.device
  1939. (only read is supported. There is no write mode).
  1940.  
  1941. See also: InitTrackDisk(),SetTDUnit(),ReadRobSectors()
  1942.  
  1943.  
  1944.  
  1945.  
  1946. JOTDStartup/SetTDUnit()
  1947.  
  1948.  
  1949. void SetTDUnit(unit) - Sets trackdisk.device emulation unit
  1950.                D0
  1951.  
  1952. This function allows to change the current virtual drive (actually it changes disks).
  1953. Use it in conjunction with TrackLoadFast(). It has no effect with ReadRobSectorsFast().
  1954.  
  1955. The unit is not limited to 3, as you can patch games which have got 4 floppies or more.
  1956.  
  1957. If this routine is not called, the unit will be 0 (default, useful for bootblocks).
  1958.  
  1959. See also: InitTrackDisk(),TrackLoad()
  1960.  
  1961.  
  1962.  
  1963.  
  1964. JOTDStartup/ReadFileFast()
  1965.  
  1966.  
  1967. ULONG ReadFileFast(filename,buffer,command,length) - Transfer a file in the given buffer
  1968.  D0                  A0      A1      D0      D1
  1969.  
  1970. Uses the Rob Northern file interface.
  1971.  
  1972. used in:
  1973.  
  1974. Cannon Fodder 2, Darkmere, Sensible Golf, Sensible Soccer, Road Rash...
  1975.  
  1976. Different versions may exist: D1 can be meaningless. In this case, set it to -1.
  1977. Some games only use commands 0 and 5
  1978.  
  1979. Darkmere uses 0, 5, 6, 7, 8 extensively.
  1980.  
  1981. in:
  1982. A0: Filename
  1983. A1: Buffer
  1984. D0: command:
  1985. D1: misc
  1986.  
  1987. D0:
  1988.  
  1989. 0: Read        
  1990.     in : D1: # bytes (-1: all), A0: filename, A1: buffer
  1991.     out: D0: 0 if OK,  D1: length read
  1992.  
  1993. 1: Write (disabled)
  1994.     in: D1: # bytes          , A0: filename, A1: buffer
  1995.     out: D0: 0 if OK,  D1: length written
  1996.  
  1997. 2: Never seen it before ????
  1998. 3: Read directory (disabled)                           A0: 
  1999. 4: Format floppy (disabled)    
  2000. 5: Get Length
  2001.     in : A0: filename
  2002.     out: D0: 1 if found, 0 else, D1: length
  2003.  
  2004. 6: Nothing (I think)
  2005.  
  2006. 7: Read last file w/ offset
  2007.     in : D1: # bytes          , A0: scratch  ,A1: buffer
  2008.         out: D0: ???
  2009.  
  2010. 8: Set offset on last accessed file
  2011.         in : D1: offset           , A0: scratch  ,A1: scratch
  2012.         out: D0: offset
  2013.  
  2014. In order to use this function, you must initialize the fastfile structure by calling
  2015. LoadFiles(), else this will fail.
  2016.  
  2017. filename: a NULL-terminated string
  2018. buffer: a pointer on a memory zone
  2019. length: the length in bytes. If you pass -1, the whole file will be read.
  2020.  
  2021. Sometimes, the games use this routine as-is, and you've got only to patch.
  2022. However, you've got to check for files which are not found: they can be savegames loads.
  2023.  
  2024. In that case, you can call the original routine (read from floppy) or make a HD access
  2025. using InGameOSCall() (much harder, provided you've got to read the directory)
  2026.  
  2027.  
  2028. To read part of files (using the 7 and 8 commands), it's better to use ReadFilePart()
  2029.  because the interface is more natural. However, this routine can be used as-is in some
  2030. games (such as Darkmere, which uses the 7 and 8 commands, and took me a while to figure
  2031. it out!)
  2032.  
  2033.  
  2034. See also: LoadFiles(),ReadFile(),ReadFilePart()
  2035.  
  2036.  
  2037.  
  2038.  
  2039. JOTDStartup/ReadRobSectors()
  2040.  
  2041.  
  2042. ULONG ReadRobSectors(drivenum,offset,blocks,command,buffer) - Reads sectors from virtual disk
  2043.  D0                    D0      D1     D2     D3      A0
  2044.  
  2045.  
  2046. This is the main all-purpose loading routine of the package. I chose this syntax
  2047. because this routine is used as-is in lots of games and can be used provided
  2048. an offset correction or a disk choice is done in many games.
  2049. I noticed it and replaced it in:
  2050.  
  2051. Assassin, BodyBlows, AlienBreed, Warzone, Magic Pockets, Cadaver,
  2052. Chaos Engine, Cannon Fodder 2, Project-X, Mortal Kombat I & II,
  2053. Gods, Rodland, Desert Strike, Qwak, and others...
  2054.  
  2055. INTERFACE:
  2056.  
  2057. drivenum/D0 = Drive Number - sometimes matches disk number
  2058. offset/D1   = Offset in bytes / 512 (also offset in sectors)
  2059. block/D2    = nb of 512 bytes sectors to read
  2060. command/D3  = 0: Read data, !=0 Writes (has to be done manually, as it's better to create a separate file for game saves)
  2061. buffer/A0   = Start address
  2062.  
  2063. For 2 disked games using DF0: and DF1:, you generally don't have to worry about disk changes,
  2064. as disk1 is supposed to be in DF0: and disk2 in DF1:, so D0 will be set in a correct way and
  2065. the game will read from the correct disk anyway.
  2066.  
  2067. See the examples to understand fully the interest of this routine.
  2068.  
  2069. Specifying the LOWMEM tooltype/argument at startup causes this
  2070. routine to read the data from the file instead of the cached images
  2071. in memory (which will not exist if LOWMEM is activated).
  2072.  
  2073. See also: TrackLoadFast(), LoadDisks(), ReadDiskPart()
  2074.  
  2075.  
  2076.  
  2077.  
  2078. JOTDStartup/ReadDiskPart()
  2079.  
  2080.  
  2081. ULONG ReadDiskPart(drivenum,length,offset,buffer) - Reads bytes from virtual disk
  2082.  D0                   D0      D1     D2     A0
  2083.  
  2084.  
  2085. Even if the Rob Northen format is widespread, this routine is the alternative.
  2086. It is able to read any number of bytes and at any location on a disk image. It's useful
  2087. for disk loaders which use a non $200 round interface.
  2088.  
  2089.  
  2090. INTERFACE:
  2091.  
  2092. drivenum/D0 = Drive Number - sometimes matches disk number
  2093. offset/D1   = Length in bytes to read
  2094. block/D2    = Offset in bytes from where to read
  2095. buffer/A0   = Start address
  2096.  
  2097. Specifying the LOWMEM tooltype/argument at startup causes this
  2098. routine to read the data from the file instead of the cached images
  2099. in memory (which will not exist if LOWMEM is activated).
  2100.  
  2101. See also: TrackLoadFast(), LoadDisks(), ReadRobSectors()
  2102.  
  2103.  
  2104.  
  2105.  
  2106. JOTDStartup/StrcpyAsm()
  2107.  
  2108.  
  2109. void StrcpyAsm(string1,string2) - Copies string
  2110.                  D0      D1
  2111.                  
  2112. Copies the string pointed by D0 to the buffer area in D1.
  2113. The source string must be NULL terminated.
  2114.  
  2115. See also: StrcmpAsm(), StrlenAsm(), ToUpper()
  2116.  
  2117.  
  2118.  
  2119.  
  2120. JOTDStartup/StrcmpAsm()
  2121.  
  2122.  
  2123. LONG StrcmpAsm(string1,string2) - Compares 2 strings (not case sensitive)
  2124.  D0              D0      D1
  2125.  
  2126. StrcmpAsm returns 0 if the 2 strings are the same (no case sensitivity,
  2127. e.g. LoA-Der is the same as LOa-deR), and -1 if they're different
  2128.  
  2129. See also: StrcmpAsm(), StrcpyAsm(), ToUpper()
  2130.  
  2131.  
  2132.  
  2133.  
  2134. JOTDStartup/StrlenAsm()
  2135.  
  2136.  
  2137. ULONG StrlenAsm(string) - Returns the length of a NULL-terminated string
  2138.  D0               D0
  2139.  
  2140.  
  2141.  
  2142.  
  2143. JOTDStartup/ToUpperAsm()
  2144.  
  2145.  
  2146. void ToUpperAsm(string) - Converts a string in upper case
  2147.  D0               D0
  2148.  
  2149.  
  2150.  
  2151.  
  2152. JOTDStartup/HexReplaceLong()
  2153.  
  2154.  
  2155. void HexReplaceLong(searched,replacer,start,end) - Searches a longword and replaces it
  2156.                        D0       D1     A0   A1
  2157.  
  2158. Designed for automatic search/replace of data/code.
  2159.  
  2160. This function can be useful to search blitter commands (move.w Dx,($58,Ax)) to patch
  2161. them with WaitBlit. For example, I'd like to insert blitterwaits in the zone
  2162. $1000-$5000 for the instruction  move.w  D1,($58,A2) (hex: $35410058)
  2163.  
  2164.     ...
  2165.     move.l   #$35410058,D0
  2166.     move.l   #$4EB800C6,D1   ; JSR ($C6).W
  2167.     lea      $1000.W,A0
  2168.     lea      $5000.W,A1
  2169.     JSRGEN   HexReplaceLong
  2170.     PATCHUSRJMP    $C6.W,DoBlit_D1A2
  2171.     ...
  2172.  
  2173. DoBlit_D1A2:
  2174.     JSRGEN   WaitBlit        ; wait blitter operations to complete
  2175.     move.w   D1,($58,A2)     ; start the blit
  2176.     rts
  2177.  
  2178. The search will be done word by word (2 bytes). Odd occurences will not be found.
  2179.  
  2180. See also: HexReplaceWord
  2181.  
  2182.  
  2183.  
  2184.  
  2185. JOTDStartup/HexReplaceWord()
  2186.  
  2187.  
  2188. void HexReplaceWord(searched,replacer,start,end) - Searches a word and replaces it
  2189.                       D0.W    D1.W     A0    A1
  2190.  
  2191. Designed for automatic search/replace of data/code.
  2192.  
  2193. Same use as HexReplaceLong().
  2194.  
  2195. The search will be done word by word (2 bytes). Odd occurences will not be found.
  2196.  
  2197. See also: HexReplaceLong()
  2198.  
  2199.  
  2200.  
  2201.  
  2202. JOTDStartup/SetFakeFunction()
  2203.  
  2204.  
  2205. void SetFakeFunction(offset, new function) - Sets user defined function in fakeexec table
  2206.                        D0       A0
  2207.  
  2208. The exec library emulation is poor. You'll have to define your own functions to make
  2209. it better (game specific or not).
  2210.  
  2211. For instance, if a game uses AllocMem(), it's up
  2212. to you to choose what to return, to keep track of the allocated blocks or not
  2213. (is it worth? is AllocMem() called more than once, twice...?)
  2214.  
  2215. You could do it in a "dirty" way, by getting FakeExecBase in $4 and patching the offset,
  2216. but I created a function for this. As a bonus, the function will check:
  2217.  
  2218. 1. That you pass an offset which is between 0 and -$300
  2219. 2. That OpenFakeExec() was called (before SaveOSData)
  2220.  
  2221. If both conditions are not passed, the function will trigger an explicit run-time error.
  2222.  
  2223. Example: define your own AvailMem()
  2224.  
  2225.        ...
  2226.        
  2227.        lea    MyOwn_AvailMem(pc),A0
  2228.        GETLVO AvailMem
  2229.        JSRGEN SetFakeFunction
  2230.        ...
  2231.  
  2232. MyOwn_AvailMem:
  2233.        move.l   #$70000,D0
  2234.        rts
  2235.  
  2236. I used my new macro GETLVO to get an LVO in D0. (move.l  #_LVO1,D0)
  2237.  
  2238. See also: OpenFakeExec()
  2239.  
  2240.  
  2241.  
  2242.  
  2243. JOTDStartup/CRC16()
  2244.  
  2245.  
  2246. UWORD    CRC16 (buffer, length) - Calculates CRC16 checksum
  2247.  D0             A0       D0
  2248.  
  2249. This routine calculates CRC16 checksum of a block according to the
  2250. ANSI CRC16 algorithm.
  2251.  
  2252. Thanks to Andreas Kleiner for putting the crc.c source on aminet,
  2253. which I converted into assembler (available on request)
  2254.  
  2255. This routine was added because of the WHDLoad slave emulation.
  2256.  
  2257.  
  2258.  
  2259.  
  2260. JOTDStartup/HexToString()
  2261.  
  2262.  
  2263. void HexToString(number,buffer) - Converts a hex number to a ascii string
  2264.                    D0    A1
  2265.  
  2266. The buffer has to be at least as wide as 10 chars. The format will always be:
  2267.  
  2268. $xxxxxxxx.
  2269.  
  2270. e.g: D0=$37 gives A1-> $00000037
  2271.      D0=$DEADBEEF gives A1-> $DEADBEEF
  2272.  
  2273.  
  2274.  
  2275.  
  2276. JOTDStartup/Save & Restore hardware registers
  2277.  
  2278.  
  2279. void SaveCustomRegs() - Save readable custom registers
  2280. void RestoreCustomRegs() - Restore previously saved custom registers
  2281. void SaveCIARegs() - Save CIA registers
  2282. void RestoreCIARegs() - Restore CIA registers
  2283.  
  2284. Those functions are used internally to save/restore intena, intreq, adkcon
  2285. dmacon, and the CIA registers from/to the operating system.
  2286. So the game can (and will) trash those registers, but they will be restored
  2287. when InGameExit() is called.
  2288. You should not use those functions, unless you know what you are doing.
  2289.  
  2290. See also: InGameExit(), SaveOSData(), SAVE_OSDATA (macro)
  2291.  
  2292.  
  2293.  
  2294.  
  2295. JOTDStartup/RNCLength()
  2296.  
  2297.  
  2298. ULONG RNCLength(memory) - returns the length of a decrunched RNC file
  2299.  D0              A0
  2300.  
  2301. This function returns 0 if the zone pointed by A0 is not a RNC crunched file.
  2302. Else, it will return the number of bytes the file will take once decrunched.
  2303.  
  2304. See also - LoadRNCFile(), RNCDecrunch()
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310. JOTDStartup/RNCDecrunch()
  2311.  
  2312.  
  2313. ULONG RNCDecrunch(crunchbuffer,decrunchbuffer) - Decrunches a RNC type 1 file
  2314.  D0                   A0            A1
  2315.  
  2316. This routine handles Rob Northen Cruncher files (header: RNC01).
  2317. This type of cruncher is very heavily used in lots of games
  2318. from EOA, Team 17, Renegade, Akklaim, and lots of others.
  2319.  
  2320. A0 points on the crunched buffer start (the file just loaded), and
  2321. A1 points on the destination.
  2322.  
  2323. This routine returns 0 if an error occured.
  2324.  
  2325. The two addresses may be the same, as the decrunch algorithm is able to
  2326. overwrite the crunched data during decrunch.
  2327. Be careful to allocate or reserve enough memory to decrunch the file.
  2328. Use the RNCLength() function to know the length of the file once decrunched.
  2329.  
  2330. LoadRNCFile uses this routine, but RNCDecrunch can be useful when the game is NONDOS
  2331. and the data is trackloaded.
  2332.  
  2333. NOTE: RNC crunched files are handled by the XFD library (decrunch only)
  2334. The cruncher (ProPack) is not freely distributable, and reserved to
  2335. game programmers.
  2336.  
  2337. See also - LoadRNCFile(), RNCLength(), RNCDecrunchEncrypted(), ATNDecrunch()
  2338.  
  2339.  
  2340.  
  2341.  
  2342. JOTDStartup/RNCDecrunchEncrypted()
  2343.  
  2344.  
  2345. ULONG RNCDecrunchEncrypted(key,crunchbuffer,decrunchbuffer) - Decrunches a RNC type 1 file, with encryption
  2346.  D0                         D0      A0            A1
  2347.  
  2348. Some games, like Walker, use RNC compression, but encrypt data with a 16/32
  2349. bit key. You'll need to know the key to be able to decrunch the file
  2350. properly. In most cases, leave the game handle that. I use this routine
  2351. because in most games the decrunch routines are located in chipmem and it's
  2352. slow. You can patch the entry of a RNC decrunch routine by this call,
  2353. which is in fastmem, and you'll be amazed by the speed.
  2354.  
  2355. See also - LoadRNCFile(), RNCLength(), RNCDecrunch(), ATNDecrunch(), PPDecrunch(),
  2356.            FungusDecrunch()
  2357.  
  2358.  
  2359.  
  2360.  
  2361. JOTDStartup/ATNDecrunch()
  2362.  
  2363.  
  2364. ULONG ATNDecrunch(crunchbuffer,decrunchbuffer) - Decrunches a ATN! file
  2365.  D0                   A0            A1
  2366.  
  2367. This routine handles ATN files (header: ATN!).
  2368. This type of cruncher is very heavily used in lots of games
  2369. from Team 17 (Arcade Pool, Project-X...)
  2370.  
  2371. A0 points on the crunched buffer start (the file just loaded), and
  2372. A1 points on the destination.
  2373.  
  2374. This routine returns 0 if an error occured.
  2375.  
  2376. The two addresses may be the same, as the decrunch algorithm is able to
  2377. overwrite the crunched data during decrunch.
  2378. Be careful to allocate or reserve enough memory to decrunch the file.
  2379. Use the ATNLength() function to know the length of the file once decrunched.
  2380.  
  2381.  
  2382. NOTE: ATN crunched files are handled by the XFD library (decrunch only)
  2383. The cruncher is not available. This cruncher no longer appears in
  2384. Team 17 games and has been replaced by RNC.
  2385.  
  2386. See also - LoadRNCFile(), RNCLength(), RNCDecrunchEncrypted()
  2387.  
  2388.  
  2389.  
  2390.  
  2391. JOTDStartup/PPDecrunch()
  2392.  
  2393.  
  2394. PPDecrunch(end_crunchbuf,start_crunchbuf,decrunchbuf) - Decrunches a PP20 file
  2395.               A0              A1            A2
  2396.  
  2397. As I saw this routine in at least one game and I know PowerPacker 
  2398. by Nico François is very popular on the amiga, I included this decrunch routine.
  2399.  
  2400. This applies to file beginning by the PP20 header (PowerPacker 2.0)
  2401.  
  2402. in: A0 end of source buffer
  2403.     A1 start of dest buffer
  2404.     A2 start of source buffer
  2405.  
  2406. out: nothing, but the buffer is decrunched :-)
  2407.  
  2408. All registers are preserved in this call.
  2409.  
  2410. See also - RNCDecrunch(), ATNDecrunch(), FungusDecrunch()
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416. JOTDStartup/FungusDecrunch()
  2417.  
  2418.  
  2419. void FungusDecrunch(crunchbuf,decrunchbuf) - Decrunches a FUNGUS file
  2420.                        A0          A1
  2421.  
  2422. The FUNGUS packer (maybe also called SF or SA packer) is mostly used
  2423. in Gremlins games (Zool, Switchblade 2...)
  2424.  
  2425. in: A0: crunched buffer start
  2426. in: A1: destination (may be the same, like in RNC decruncher)
  2427.  
  2428. CAUTION: This decrunch routine does not check that the data is correct.
  2429. Unreliable results may occur if you try to decrunch a random block of memory.
  2430.  
  2431. See also - RNCDecrunch(), ATNDecrunch(), PPDecrunch()
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  
  2437. JOTDStartup/BlackScreen()
  2438.  
  2439.  
  2440. void BlackScreen() - Sets all the colors to black
  2441.  
  2442. This function will not build a copperlist. It will just clear color registers.
  2443.  
  2444.  
  2445.  
  2446.  
  2447. JOTDStartup/EnterDebugger()
  2448.  
  2449.  
  2450. void EnterDebugger(void) - Enters debugger if one is installer
  2451.  
  2452. ATM only HRTMon is property supported. A version of HRTMon which works is for instance
  2453. 2.22. All versions above this one work too.
  2454.  
  2455. EnterDebugger calls the debugger just as if you put a breakpoint there, except that
  2456. you don't have too :)
  2457. VERY useful function when the loader is in development phase, to remove afterwards!
  2458.  
  2459. This function will do nothing if no debugger was found. Run JST with VERBOSE or TEST on
  2460. to see which debugger is currently loaded.
  2461.  
  2462. See also: 
  2463.  
  2464.  
  2465.  
  2466.  
  2467. JOTDStartup/SetTraceVector()
  2468.  
  2469.  
  2470. APTR SetTraceVector(APTR trace_entrypoint) - sets trace vector to a user routine
  2471.  A0                  A0
  2472.  
  2473. Now that JST relocates the VBR (unless you use the VBR-specific tooltypes), it's no
  2474. longer possible to poke directly in the trace exception vector to install a tracer
  2475. by poking in $24, since JST will intercept the trace exception with the relocated VBR.
  2476.  
  2477. This function allows to do it transparently.
  2478.  
  2479. in: A0 points to your trace code. Of course it's up to you to preserve registers on exit.
  2480.     Exit by RTE (not RTS)
  2481.  
  2482. out: A0 points to the old trace code. Most of the time it's the routine JST installed.
  2483.  
  2484. See also: 
  2485.  
  2486.  
  2487.  
  2488.  
  2489. JOTDStartup/WaitMouse()
  2490.  
  2491.  
  2492. void WaitMouse(void) - Waits for LMB while the screen is full of colors
  2493.  
  2494. Useful to see if a point is reached. Waits until the LMB is pressed to exit.
  2495.  
  2496.  
  2497. See also: WaitMouseInterrupt()
  2498.  
  2499.  
  2500.  
  2501.  
  2502. JOTDStartup/WaitMouseInterrupt()
  2503.  
  2504.  
  2505. void WaitMouseInterrupt(void) - Waits for LMB while the screen is full of colors, interrupts active
  2506.  
  2507. Same routine as WaitMouse() except that as a bonus, interrupts will be enabled during the
  2508. wait, allowing you to break with a software debugger like HRTMon.
  2509.  
  2510. But this function can lead to crashes in some cases (e.g. the interrupts were disabled
  2511. because the interrupts vectors were not set by the game yet)
  2512.  
  2513. See also: WaitMouse()
  2514.  
  2515.  
  2516.  
  2517.  
  2518. JOTDStartup/InGameExit()
  2519.  
  2520.  
  2521. void InGameExit() - returns to the OS while the game is running
  2522.  
  2523. This function will return with a rts if no memory was available
  2524. for the chipmem (SaveOSData()). The best way to call it is from
  2525. a JSRGEN, then return to the program if it could not quit.
  2526.  
  2527. This function was moved from the absolute part to the relocatable part
  2528. in order to avoid crashes when the absolute program has be overridden
  2529. by the game. JSRABS InGameExit will not work (it will not crash in
  2530. most cases but will do nothing).
  2531.  
  2532. Now you can call this function before having called SaveOSData()
  2533. or the SAVE_OSDATA macro from the user program.
  2534.  
  2535. Call it whenever you want during the game, even if the OS
  2536. is totally killed. This function will resurrect the OS and will
  2537. call the user routine you specified using the SetExitRoutine function
  2538. if any. (see macro HDPARAMS)
  2539.  
  2540. This function has be greatly improved. It succeeds on 99.9% of games.
  2541.  
  2542. See also: SaveOSData(), InGameOSCall()
  2543.  
  2544.  
  2545.  
  2546.  
  2547. JOTDStartup/IsRegistered()
  2548.  
  2549.  
  2550. ULONG IsRegistered(void) - Check if the current version of JST is registered
  2551.   D0
  2552.  
  2553. Returns 0 in D0 if the version of JST currently used is not registered
  2554. Returns 1 in D0 if the version of JST currently used is registered (from v1.1e)
  2555.  
  2556. See also: 
  2557.  
  2558.  
  2559.  
  2560.  
  2561. JOTDStartup/SetExitRoutine()
  2562.  
  2563.  
  2564. void SetExitRoutine(routine entrypoint) - calls a user routine on exit
  2565.                           A0
  2566.  
  2567. This function will allow the user to specify a function to call
  2568. when the OS has been restored with InGameExit(). For instance, this function
  2569. can save scores to a file without the use of WriteFileHD but in a normal DOS
  2570. way, or can display a message, free some manually allocated memory...
  2571.  
  2572. If you want to save scores on exit which are located in chip memory,
  2573. remember that you'll have to copy the scores in fastmem before calling
  2574. InGameExit, or the buffer will be trashed by the OS chipmem.
  2575.  
  2576. The user routine must end by RTS.
  2577.  
  2578. CAUTION: The input was D0 and now it's A0 because it's more convenient for
  2579. relocatable code.
  2580.  
  2581. See also: InGameExit()
  2582.  
  2583.  
  2584.  
  2585.  
  2586. JOTDStartup/InGameIconify()
  2587.  
  2588.  
  2589. void InGameIconify() - returns to the OS while the game is running, with possibility of return
  2590.  
  2591. This function acts exactly like InGameExit BUT it allows to return to the game!
  2592. That seems impossible to do because of the read only registers, that's why some special
  2593. functions are to be applied on the game before you can use this function.
  2594.  
  2595. Actually, JST is already able to swap the OS but the display, because the copper pointer
  2596. is ready only.
  2597. But you can use some other functions to patch the game at some strategic locations
  2598. when it stores the copperlist pointer into the copper pointer register (COP1LC, $80).
  2599.  
  2600. Those functions modify the MOVE instruction which are used to store the
  2601. copperlist pointer very easily.
  2602.  
  2603. Copperlist pointer store can be of these types:
  2604.  
  2605. 1:    move.l    Ax,($80,Ay)
  2606. 2:    move.l    #chipaddr,($80,Ay)
  2607. 3:    move.l    addr,($80,Ay)
  2608. 4:    move.l    #chipaddr,$DFF080
  2609. 5:    move.l    addr,$DFF080
  2610. 6:    move.l    Ax,$DFF080
  2611.  
  2612. There are many ways to store a copperlist pointer, but those are the most frequent occurences.
  2613.  
  2614. --
  2615.  
  2616. CASE 1:
  2617.  
  2618. To search (and patch) case 1, you can use HexReplaceLong() because this instruction is
  2619. 4 bytes long and is totally determined once you found which registers the game is using
  2620. (with HRTMon just search with fi and the pattern A*,($80,A*) )
  2621.  
  2622. Replace the instruction by $4EB8addr where $addr is a zero page address where you can
  2623. put the storage code or put a PATCHUSRJMP to a user routine (I prefer that second solution)
  2624.  
  2625. Be careful of the range, and check the locations you patch are actually copper moves
  2626. (just ensure Ay contains $DFF000), or else the iconify could go bezerk
  2627. (but the game will still work)
  2628.  
  2629. In that use routine, you'll put the value in the copper pointer and register it to JST
  2630. using the SetCopperPointer() function. You've done it.
  2631.  
  2632. This is the most difficult and manual case, but when you're used to it, that's not a concern
  2633. anymore.
  2634.  
  2635. CASE 2:
  2636.  
  2637. You lucky guys I made a special search and patch routine for those frequent occurences.
  2638. It's called PatchMoveCList_Idx(). There are a couple of parameters
  2639. but it's very easy to use and totally transparent.
  2640. You've got to put it at the right place, that's all.
  2641.  
  2642.  
  2643. CASE 3:
  2644.  
  2645. Like in case 2, I also made a routine called PatchMoveCList_Abs()
  2646.  
  2647. CASE 4:
  2648.  
  2649. Like in case 2, I also made a routine called PatchMoveCList_Ind()
  2650.  
  2651. CASE 5:
  2652.  
  2653. No routine implemented in JST. Totally manual method. I may add a PatchMoveCList_xxx function
  2654. later but now I don't feel like doing it.
  2655.  
  2656. CASE 6:
  2657.  
  2658. Well, totally manual method, but easy. Note down the addresses, and then make a PATCHUSRJSR
  2659. to your user routine (the instruction is also 6 bytes long)
  2660. which will do the poke in the copperlist register and will log
  2661. the copper pointer value to JST using SetCopperPointer().
  2662.  
  2663. --
  2664.  
  2665. If you cannot find in copperlist store instruction belonging to those 6 cases above, 
  2666. you'll have to search further, but game coders usually don't hide this kind
  2667. of instruction too much (it can happen, though, when sometimes they try to fool
  2668. the Action Replay cartridges).
  2669.  
  2670. You've got another solution if you don't find the copperlist pointer: look into the game
  2671. using Action Replay cartridge (or equivalent) or do a copper search with HTRMon.
  2672. If the copperlist location does not move, you can hardcode it in your program and call
  2673. SetCopperPointer() with this address.
  2674.  
  2675.  
  2676. When you logged all the copperlist pointer store instructions, InGameIconify can be called
  2677. exactly like InGameExit, using for instance the TAB key in the keyboard interrupt.
  2678.  
  2679. In some cases, you'll have to set some hardware registers 'by hand' after JST resumes the game.
  2680. For instance, I had to put a move.w #$400F,fmode+$DFF000 in Street Racer, or else the display
  2681. was trashed.
  2682. But in some games like Menace or Lotus, the iconification works perfectly.
  2683.  
  2684. InGameIconify won't do anything if the current copperlist pointer is set to 0.
  2685. You can set it to this value with StoreCopperPointer()
  2686.  
  2687. See the examples (Menace, Street Racer, Lotus Turbo Challenge) to figure out how to do
  2688. this.
  2689.  
  2690. Warning: QUIET will prevent this function to work. It will do nothing in that case. Just
  2691. because JST uses the console in the iconify menu.
  2692.  
  2693. See also: InGameExit(), StoreCopperPointer(), TellCopperPointer(), PatchMoveCList_Idx(),
  2694.           PatchMoveCList_Abs(), HexReplaceLong()
  2695.  
  2696.  
  2697.  
  2698.  
  2699. JOTDStartup/PatchMoveCList_Abs()
  2700.  
  2701.  
  2702. void PatchMoveCList_Abs(start, end, trap_number) - patches copper list stores: move.l #adr,$DFF080
  2703.                          A0     A1     D1
  2704.  
  2705. This function puts a TRAP when it finds a MOVE.L #ADR,$DFF080 instruction.
  2706. ADR is checked so no patch is done if ADR is not in chipmem.
  2707.  
  2708. If D1 is out of $0-$F range, this function will do nothing. You can usually choose any of those
  2709. numbers (which match trap numbers location $80 ->$BC), but some games use some traps, and
  2710. obviously you cannot use the same ones. You'd be very unlucky if the game used ALL the traps.
  2711. In that case, you've got to patch manually.
  2712.  
  2713. A0: start address: MUST BE AN EVEN ADDRESS!
  2714. A1: end address
  2715. D1: trap number ($0-$F)
  2716.  
  2717. This function flushes the caches at the end of the operation.
  2718.  
  2719. See also: PatchMoveCList_Idx(), PatchMoveCList_Ind(), InGameIconify()
  2720.  
  2721.  
  2722.  
  2723.  
  2724.  
  2725. JOTDStartup/PatchMoveCList_Ind()
  2726.  
  2727.  
  2728. void PatchMoveCList_Ind(start, end, trap_number) - patches copper list stores: move.l adr,$DFF080
  2729.                          A0     A1     D1
  2730.  
  2731. This function puts a TRAP when it finds a MOVE.L ADR,$DFF080 instruction.
  2732. ADR is checked so no patch is done if ADR is not in chipmem.
  2733.  
  2734. If D1 is out of $0-$F range, this function will do nothing. You can usually choose any of those
  2735. numbers (which match trap numbers location $80 ->$BC), but some games use some traps, and
  2736. obviously you cannot use the same ones. You'd be very unlucky if the game used ALL the traps.
  2737. In that case, you've got to patch manually.
  2738.  
  2739. A0: start address: MUST BE AN EVEN ADDRESS!
  2740. A1: end address
  2741. D1: trap number ($0-$F)
  2742.  
  2743. This function flushes the caches at the end of the operation.
  2744.  
  2745. See also: PatchMoveCList_Idx(), PatchMoveCList_Abs(), InGameIconify()
  2746.  
  2747.  
  2748.  
  2749.  
  2750.  
  2751. JOTDStartup/PatchMoveCList_Idx()
  2752.  
  2753.  
  2754. void PatchMoveCList_Idx(start, end, register#, trap#) - patches copper list stores: move.l #adr,($80,Ax)
  2755.                          A0     A1     D0       D1
  2756.  
  2757. This function puts a TRAP when it finds a MOVE.L #ADR,($80,Ax) instruction if the
  2758. register number you specified matches Ax. It stores the copper pointer so InGameIconify
  2759. knows where it is.
  2760.  
  2761. ADR is checked so no patch is done if ADR is not in chipmem.
  2762.  
  2763. This function will do nothing if D1 is out of $0-$F range or if D0 is out of 0-6 range.
  2764. Most of the time, you can choose any of those numbers $0-$F for D1
  2765. (which match trap numbers location $80 ->$BC) but some games use some traps, and
  2766. obviously you cannot use the same ones. You'd be very unlucky if the game used ALL the traps.
  2767. In that case, you've got to patch manually (hard luck!)
  2768.  
  2769. A0: start address: MUST BE AN EVEN ADDRESS!
  2770. A1: end address
  2771. D0: register number (0-6)
  2772. D1: trap number ($0-$F)
  2773.  
  2774. This function flushes the caches at the end of the operation.
  2775.  
  2776. See also: PatchMoveCList_Abs(), PatchMoveCList_Ind(), InGameIconify()
  2777.  
  2778.  
  2779.  
  2780.  
  2781.  
  2782. JOTDStartup/PatchMoveBlit_Idx()
  2783.  
  2784.  
  2785. void PatchMoveBlit_Idx(start, end, register#, trap#) - patches blit moves: move.w #adr,($58,Ax)
  2786.                         A0     A1     D0       D1
  2787.  
  2788. This function puts a TRAP when it finds a MOVE.W #ADR,($58,Ax) instruction if the
  2789. register number you specified matches Ax.
  2790. The trap performs the blit but calls WaitBlit() before, so the
  2791. blitter is always ready and there are no blitter errors due to those calls.
  2792.  
  2793. This function will do nothing if D1 is out of $0-$F range or if D0 is out of 0-6 range.
  2794. Most of the time, you can choose any of those numbers $0-$F for D1
  2795. (which match trap numbers location $80 ->$BC) but some games use some traps, and
  2796. obviously you cannot use the same ones. You'd be very unlucky if the game used ALL the traps.
  2797. In that case, you've got to patch manually (hard luck!)
  2798.  
  2799. A0: start address: MUST BE AN EVEN ADDRESS!
  2800. A1: end address
  2801. D0: register number (0-6)
  2802. D1: trap number ($0-$F)
  2803.  
  2804. This function flushes the caches at the end of the operation.
  2805.  
  2806. See also: WaitBlit()
  2807.  
  2808.  
  2809.  
  2810.  
  2811.  
  2812. JOTDStartup/StoreCopperPointer()
  2813.  
  2814.  
  2815. void StoreCopperPointer(cptr) - Logs the current (believed) copperlist pointer to JST
  2816.                          D0
  2817.  
  2818. D0 can be guessed or read from an instruction in the game.
  2819.  
  2820. Passing -1.L to this function will disable Iconification (JST believes the copperlist
  2821. is not known anymore)
  2822.  
  2823. See also: InGameIconify(), TellCopperPointer(), PatchMoveCList_Abs(), PatchMoveCList_Idx()
  2824.  
  2825.  
  2826.  
  2827.  
  2828. JOTDStartup/TellCopperPointer()
  2829.  
  2830.  
  2831. ULONG TellCopperPointer(void) - Returns the current logged copperlist pointer
  2832.  D0   
  2833.  
  2834. Gets current copperlist pointer if you had logged the copperlist moves.
  2835.  
  2836. This function will return -1.L if the copperlist has not been logged yet.
  2837.  
  2838. See also: InGameIconify(), TellCopperPointer(), PatchMoveCList_Abs(), PatchMoveCList_Idx()
  2839.  
  2840.  
  2841.  
  2842.  
  2843. JOTDStartup/BeamDelay()
  2844.  
  2845.  
  2846. void BeamDelay(beamticks) - waits using VPOSR register
  2847.                   D0.W
  2848.  
  2849. This function will wait approx. D0*20ms.
  2850. Use it to fix some CPU dependent loops like
  2851.  
  2852. loop
  2853.     dbf    Dx,loop
  2854.  
  2855. by dividing Dx by #$28 and calling BeamDelay
  2856. with value of Dx in D0
  2857. (problem mentionned by Harry in some Soundtracker replay routines)
  2858.  
  2859.     move.w    Dx,D0
  2860.     divu    #$28,D0
  2861.     swap    D0
  2862.     clr.w    D0
  2863.     swap    D0
  2864.     JSRGEN    BeamDelay
  2865. (or     BEAM_DELAY    D0)
  2866.  
  2867.  
  2868. See also: BEAM_DELAY (macro)
  2869.  
  2870.  
  2871.  
  2872.  
  2873. JOTDStartup/WaitBlit()
  2874.  
  2875.  
  2876. void WaitBlit(void) - waits for blitter operations to complete
  2877.  
  2878. This small routine, inserted at the proper location, allows to avoid
  2879. blitter gfx bugs in loads of games (DoodleBug, Premiere, James Pond,
  2880. Ninja Spirit...)
  2881. and avoid crashes due to those blitter bugs (Lotus I, Lotus III, X-Out...)
  2882.  
  2883. You can either insert it before the blit (better) or after the blit
  2884. (safer, but can slowdown the game)
  2885.  
  2886. A blit is a write access to register $DFF058. See the JOTDHDInstall.guide
  2887. to learn how to find those faulty blits.
  2888.  
  2889. See also: WAIT_BLIT (macro)
  2890.  
  2891.  
  2892.  
  2893.  
  2894. JOTDStartup/SetQuitKey()
  2895.  
  2896.  
  2897. void SetQuitKey(key,user_routine) - Activates auto quit key
  2898.                 D0       A0
  2899.  
  2900. D0: raw keycode
  2901. A0: user routine to be called before InGameExit
  2902.  
  2903. If A0=0, then no user routine will be called (default exit)
  2904.  
  2905. Note: Ralf prefered this feature to be reserved to registered users only. That's his
  2906. will, and since he coded the stuff, I only have to agree.
  2907.  
  2908. If QUITKEY tooltype is set, SetQuitKey will use the QUITKEY tooltype value instead of
  2909. the loader built-in value.
  2910.  
  2911. See also: SAVEOS_DATA (macro), SetIconifyKey()
  2912.  
  2913.  
  2914.  
  2915.  
  2916. JOTDStartup/SetIconifyKey()
  2917.  
  2918.  
  2919. ULONG SetIconifyKey(key,user_routine) - Activates auto iconify key
  2920.  D0                  D0       A0
  2921.  
  2922. D0: raw keycode (if D0 is 0 no iconify will be attempted)
  2923. A0: custom code which will be called:
  2924.      *before* InGameIconify with D0 = 0
  2925.      *after* InGameIconify with D0 = 1
  2926.  
  2927. If A0=0, then no user routine will be called.
  2928.  
  2929. If the Custom code returns with D0 != 0 no iconify will be performed
  2930.  
  2931.  
  2932. Remember that installing a iconify feature on a loader is tricky.:)
  2933.  
  2934. Note: Ralf prefered this feature to be reserved to registered users only. That's his
  2935. will, and since he coded the stuff, I only have to agree. If used with a non-registered
  2936. JST, this routine will do nothing.
  2937.  
  2938. If QUITKEY tooltype is set, SetQuitKey will use the QUITKEY tooltype value instead of
  2939. the loader built-in value.
  2940.  
  2941. See also: InGameIconify(), SetQuitKey()
  2942.  
  2943.  
  2944.  
  2945.  
  2946. JOTDStartup/LogPatch()
  2947.  
  2948.  
  2949. void LogPatch(address,length) - tells JST the patches you're going to do
  2950.                 A0      D0
  2951.  
  2952. PATCHUSRJSR, PATCHUSRJMP, PATCH_RTS, PATCHGENJSR and PATCHGENJMP include this function
  2953. automatically if PATCH_LOGGED variable is set.
  2954.  
  2955. LogPatch saves D0 bytes of the memory at location A0. Useful to save the bytes you
  2956. patch upon.
  2957.  
  2958. The log file is called "patch.log". It is saved on exit in the current directory
  2959. or the directory specified by SAVEDIR. This logfile can be analysed using the
  2960. printlog tool.
  2961.  
  2962. See also: InitLogPatch, REGISTER_PATCH (macro)
  2963.  
  2964.  
  2965.  
  2966.  
  2967. JOTDStartup/InitLogPatch()
  2968.  
  2969.  
  2970. void InitLogPatch(void) - Initializes patch logging
  2971.  
  2972. Internal use. Called if the PATCH_LOGGED constant is defined in your loader BEFORE
  2973. the jst.i include.
  2974.  
  2975. See also: LogPatch, REGISTER_PATCH (macro)
  2976.  
  2977.  
  2978.  
  2979.  
  2980. JOTDStartup/The printlog tool
  2981.  
  2982.  
  2983. This tool is used to turn the binary patch.log files into viewable text.
  2984. This is very useful to update loaders to newer versions, which are generally
  2985. slightly different than the one you're already done...
  2986.  
  2987. Usage:
  2988.  
  2989. printlog <logfile> [<sourcefile>] [NOZPAGE]
  2990.  
  2991. logfile (compulsory): the logfile generated with JST (patch.log)
  2992. sourcefile (optionnal): put your asm source file here. When a patch address is found,
  2993.     printlog makes a "grep" in your sourcefile and displays the line used to patch this location
  2994.     of course your sourcefile is NEVER written into.
  2995. NOZPAGE: does not show zero page patches matches in the sourcefile (if you patched in $D0, you
  2996.     can have a trifle of lines matched :) )
  2997.  
  2998. Redirect the output to a file to see the patches you applied.
  2999.  
  3000. See also: LogPatch(), REGISTER_PATCH
  3001.  
  3002.  
  3003.  
  3004.  
  3005.